猿问

是否应该在长时间运行的进程中留下空闲线程?

我正在创建一个旨在长期运行并监听工作的 go 程序。当它收到请求时,它会在进程队列上运行工作。

我是 golang 和系统编程的新手,所以我的问题是:我应该在程序启动时启动进程队列(它有多个空闲的工作线程)(它们会一直坐在那里直到工作进入)还是我应该旋转它们工作到达时启动并在完成时关闭它们?

我不清楚多个空闲线程将具有的整体系统影响,但我假设由于它们处于空闲状态,因此在工作到达之前不会产生任何影响。话虽如此,我想确保我的程序是一个“好邻居”并且尽可能高效。

- 编辑 -

澄清一下,“进程池”是一组在通道上等待工作的工作程序。它们应该在工作到来时启动/停止,还是在程序启动时启动并等待工作到来?


喵喔喔
浏览 160回答 3
3回答

慕工程0101907

两种方式的成本都非常低。goroutines 不需要单独的操作系统线程,并且在阻塞通道接收时几乎不消耗资源,但启动的成本也很低,因此也没有充分的理由让它们保持打开状态。我的代码很少使用工作池。通常,我的生产者会为其生成的每个工作单元生成一个 goroutine,并将其与响应通道一起直接传递出去,然后生成一个“侦听器”,它对工作输出进行一些格式化并将所有响应通过管道返回到主线程。我的常见模式如下:func Foo(input []interface{}) resp chan interface{} {&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; resp := make(chan interface{})&nbsp; &nbsp; listen := make(chan interface{})&nbsp; &nbsp; theWork := makeWork(input)&nbsp; &nbsp; // do work&nbsp; &nbsp; for _, unitOfWork := range theWork {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // doWork has signature:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; &nbsp;func doWork(w interface{}, ch chan interface{})&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doWork(unitOfWork, listen)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; }()&nbsp; &nbsp; }&nbsp; &nbsp; // format the output of listen chan and send to resp chan&nbsp; &nbsp; // then close resp chan so main can continue&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; for r := range listen {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; resp <- doFormatting(r)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; close(resp)&nbsp; &nbsp; }()&nbsp; &nbsp; // close listen chan after work is done&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; &nbsp; &nbsp; close(listen)&nbsp; &nbsp; }()&nbsp; &nbsp; return resp}然后我的主函数将一些输入传递给它并监听响应通道func main() {&nbsp; &nbsp; loremipsum := []string{"foo", "bar", "spam", "eggs"}&nbsp; &nbsp; response := Foo(loremipsum)&nbsp; &nbsp; for output := range response {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(output)&nbsp; &nbsp; }}

临摹微笑

首先,您不能使用标准 Go 库创建线程。在 Go Universe 中,您应该使用 goroutines,即所谓的绿色线程。通常你不应该产生“可重用的”goroutine。它们的创建成本很低,因此在工作任务到达时按需创建它们,并在工作完成后立即完成(从 goroutine 返回)。也不要犹豫,创建嵌套的 goroutines。通常,如果您觉得应该以并发方式做某事并且不要尝试重用它们,那么像疯了一样生成它们,因为它没有意义。

慕的地8271018

任务队列和等待工人的模式在 Go 中很常见。Goroutines 很便宜,但执行顺序是不确定的。因此,如果您希望您的系统行为是可预测的,您最好通过循环或其他方式请求的无缓冲通道控制工作人员与主程序的会合。否则,其中一些可以生成但保持空闲状态,这是合法的。
随时随地看视频慕课网APP

相关分类

Go
我要回答