[英]gomaxprocs ignored when more workers are explicityl called
我如何使用 gomaxprocs? 下面的代码设置了 gomaxprocs,但随后会产生更多的工人。 我预计有 2 个进程,但仍有 5 个进程在运行。
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
func worker(i int, waiter chan struct{}, wg *sync.WaitGroup) {
defer func(waiter chan struct{}, wg *sync.WaitGroup) {
fmt.Printf("worker %d done\n", i)
wg.Done()
<-waiter
}(waiter, wg)
fmt.Printf("worker %d starting\n", i)
time.Sleep(time.Second)
}
func main() {
runtime.GOMAXPROCS(2)
var concurrency = 5
var items = 10
waiter := make(chan struct{}, concurrency)
var wg sync.WaitGroup
for i := 0; i < items; i++ {
wg.Add(1)
waiter <- struct{}{}
go worker(i, waiter, &wg)
}
wg.Wait()
}
Go对于C/C++程序员认为的线程有3个概念:G、P、M。
没有用于限制 Ms 数量的 Go API。没有用于限制 G 数量的 API - 每次go func(...)
时都会创建一个新的。 GOMAXPROCS
是用来限制 Ps 的。
每个 P 用于跟踪一些正在运行的 Goroutine 的运行时间 state。
您应该将GOMAXPROCS
视为致力于运行Goroutines 的 Ms 的峰值数量。 (还有其他 Ms 不运行 Goroutines,但处理垃圾收集任务并作为模板线程根据需要创建新的 Ms 等。一些 Ms 致力于保持运行时 state 而一些 Go 代码被阻塞在系统调用中。)
因此,就程序中的代码而言, GOMAXPROCS
是对其 Go 代码执行的并行程度的约束。 当一个正在运行的 Goroutine 到达它被阻塞的点时,它被停放并且它的 P 用于恢复执行其他未被阻塞的 Goroutine。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.