繁体   English   中英

当更多的工人被显式调用时,gomaxprocs 被忽略

[英]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。

  • M = 实际线程
  • G = Goroutines(即你程序中的代码)
  • P = 处理器

没有用于限制 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM