我们在go中知道,当goroutine必须执行阻塞调用时,例如系统调用,或者通过cgo调用C库时,可能会创建一个线程。部分测试代码:
package main
import (
"io/ioutil"
"os"
"runtime"
"strconv"
)
func main() {
runtime.GOMAXPROCS(2)
data, err := ioutil.ReadFile("./55555.log")
if err != nil {
println(err)
return
}
for i := 0; i < 200; i++ {
go func(n int) {
for {
err := ioutil.WriteFile("testxxx"+strconv.Itoa(n), []byte(data), os.ModePerm)
if err != nil {
println(err)
break
}
}
}(i)
}
select {}
}
当我运行它时,它并没有创建很多线程。
➜ =99=[root /root]$ cat /proc/9616/status | grep -i thread
Threads: 5
有什么想法吗?
最佳答案
我稍微修改了你的程序以输出更大的 block
package main
import (
"io/ioutil"
"os"
"runtime"
"strconv"
)
func main() {
runtime.GOMAXPROCS(2)
data := make([]byte, 128*1024*1024)
for i := 0; i < 200; i++ {
go func(n int) {
for {
err := ioutil.WriteFile("testxxx"+strconv.Itoa(n), []byte(data), os.ModePerm)
if err != nil {
println(err)
break
}
}
}(i)
}
select {}
}
这会如您所料显示 >200 个线程
$ cat /proc/17033/status | grep -i thread
Threads: 203
所以我认为系统调用在您的原始测试中退出得太快,无法显示您预期的效果。
关于multithreading - golang写文件阻塞了很多goroutine,为什么不创建很多线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28186361/