我正在构建一个Go应用程序,它使用了一个“工人池”的goroutines,最初我开始创建一个池创造了一些工人。我想知道一个多核处理器的最佳工作人员数量是多少,例如,在一个有4个核心的CPU中?我目前正在使用以下方法:
// init pool
numCPUs := runtime.NumCPU()
runtime.GOMAXPROCS(numCPUs + 1) // numCPUs hot threads + one for async tasks.
maxWorkers := numCPUs * 4
jobQueue := make(chan job.Job)
module := Module{
Dispatcher: job.NewWorkerPool(maxWorkers),
JobQueue: jobQueue,
Router: router,
}
// A buffered channel that we can send work requests on.
module.Dispatcher.Run(jobQueue)目前正在全面实施
job.NewWorkerPool(maxWorkers)和module.Dispatcher.Run(jobQueue)
我使用工作池的用例:我有一个服务,它接受请求,调用多个外部API,并将结果聚合到一个响应中。每个调用都可以独立于其他调用,因为结果的顺序并不重要。我将调用分派到工人池,在那里,每个调用都是以异步方式在一个可用的goroutine中完成的。当完成工作线程时,我的“请求”线程一直在监听返回通道,同时获取和聚合结果。完成所有操作后,最终的聚合结果将作为响应返回。因为每个外部API调用可能呈现可变的响应时间,所以有些调用可以比其他调用更早地完成。根据我的理解,以并行的方式做它在性能上会比以同步的方式一个接一个地调用每个外部API要好。
发布于 2017-12-24 11:00:19
示例代码中的注释表明,您可能将GOMAXPROCS和工作池这两个概念混为一谈。这两个概念在Go中完全不同。
GOMAXPROCS设置Go运行时将使用的最大CPU线程数。这默认为在系统上找到的CPU核数,并且几乎不应该被更改。如果您想要显式地限制Go程序使用比可用CPU更少的CPU,那么您可以将其设置为1,例如,即使在4核CPU上运行时也是如此。这在罕见的情况下才会起作用。
TL;DR;从不手动设置runtime.GOMAXPROCS。最后,GOMAXPROCS和工作池的唯一关联方式是与GOMAXPROCS的关系相同。来自医生们
GOMAXPROCS变量限制可以同时执行用户级Go代码的操作系统线程的数量。代表Go代码在系统调用中阻止线程的数量没有限制;这些线程不包括GOMAXPROCS限制。此软件包的GOMAXPROCS函数查询并更改限制。
从这个简单的描述,可以很容易地看到,可能有更多(潜在的数十万.或者更多)(GOMAXPROCS)--GOMAXPROCS只限制了多少“可以同时执行用户级Go代码的操作系统线程”--而目前还没有执行用户级Go代码的goroutines并不算在内。而在I/O绑定的goroutines中(比如那些等待网络响应的)没有执行代码。因此,您有一个理论上最大的大猩猩数量,仅限于您的系统的可用内存。
https://stackoverflow.com/questions/47958826
复制相似问题