我可以无痛地使用多少个 goroutine?例如维基百科说,在 Erlang 中可以创建 2000 万个进程而不会降低性能。
Update:我刚刚研究 goroutine 性能一点点,得到了这样的结果:
- 看起来 goroutine 的生命周期比计算 sqrt() 1000 次要长(对我来说约为 45μs),唯一的限制是内存
- Goroutine 花费 4 — 4.5 KB
如果一个 goroutine 被阻塞,除了以下之外不会涉及任何成本:
成本(就内存和实际开始执行 goroutine 的平均时间而言)是:
Go 1.6.2 (April 2016)
32-bit x86 CPU (A10-7850K 4GHz)
| Number of goroutines: 100000
| Per goroutine:
| Memory: 4536.84 bytes
| Time: 1.634248 µs
64-bit x86 CPU (A10-7850K 4GHz)
| Number of goroutines: 100000
| Per goroutine:
| Memory: 4707.92 bytes
| Time: 1.842097 µs
Go release.r60.3 (December 2011)
32-bit x86 CPU (1.6 GHz)
| Number of goroutines: 100000
| Per goroutine:
| Memory: 4243.45 bytes
| Time: 5.815950 µs
在安装了 4 GB 内存的机器上,这将 goroutine 的最大数量限制为略低于 100 万个。
源代码(如果您已经了解上面打印的数字,则无需阅读此内容):
package main
import (
"flag"
"fmt"
"os"
"runtime"
"time"
)
var n = flag.Int("n", 1e5, "Number of goroutines to create")
var ch = make(chan byte)
var counter = 0
func f() {
counter++
<-ch // Block this goroutine
}
func main() {
flag.Parse()
if *n <= 0 {
fmt.Fprintf(os.Stderr, "invalid number of goroutines")
os.Exit(1)
}
// Limit the number of spare OS threads to just 1
runtime.GOMAXPROCS(1)
// Make a copy of MemStats
var m0 runtime.MemStats
runtime.ReadMemStats(&m0)
t0 := time.Now().UnixNano()
for i := 0; i < *n; i++ {
go f()
}
runtime.Gosched()
t1 := time.Now().UnixNano()
runtime.GC()
// Make a copy of MemStats
var m1 runtime.MemStats
runtime.ReadMemStats(&m1)
if counter != *n {
fmt.Fprintf(os.Stderr, "failed to begin execution of all goroutines")
os.Exit(1)
}
fmt.Printf("Number of goroutines: %d\n", *n)
fmt.Printf("Per goroutine:\n")
fmt.Printf(" Memory: %.2f bytes\n", float64(m1.Sys-m0.Sys)/float64(*n))
fmt.Printf(" Time: %f µs\n", float64(t1-t0)/float64(*n)/1e3)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)