go - 最大 goroutine 数

标签 go multitasking goroutine

我可以无痛使用多少个 goroutine?例如维基百科说,在 Erlang 中可以创建 2000 万个进程而不会降低性能。

更新:我刚刚 investigated in goroutines performance一点点,得到了这样的结果:

  • 看起来 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)
}

关于go - 最大 goroutine 数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8509152/

相关文章:

go - 如何停止正在监听 RethinkDB 变更源的 goroutine?

multithreading - 这是Go中的惯用工作线程池吗?

iphone - iOS 多任务跟踪 GPS 位置

iphone - 在基于选项卡的应用程序中向 viewController 发送消息(iphone iOS)

屏幕锁定时 iOS 背景音频停止

go - Goroutines节气门示例

go - 如何使用 API 列出 GCP 项目中的所有图像 URL?

postgresql - 如何使用 go pg CRUD Postgres Point 数据类型

Azure SQL 数据库错误 TLS 握手自 v12 升级以来失败

mysql - SetMaxOpenConns() 无法解决 `Error 1040: Too many connections`