go - Go中的多线程无限循环
问题描述
为了帮助扩展我的围棋知识,我决定为Collatz 猜想编写一个迭代器。让它工作后,我现在想让它成为多线程的。我可以找到多线程 for 循环的各种示例,但它们似乎是基于定义边界之间的每次迭代的线程。例如for n := range(10) {
。在我的用例中,N 的上限是未知的(取决于代码运行多长时间)。完整的代码可以在 Github上看到,但总结一下:
n := 0
for {
stepsToResolve = resolveN(n) //<- "Multithread this"
n++
}
解决方案
您的示例缺少退出条件,因此有点奇怪。话虽如此,您并不总是事先知道您将要启动多少子程序。处理此问题的典型方法是使用sync.WaitGroup
. 例如:
for {
wg.Add(1) // declare new goroutine
go func(i int, wg *sync.WaitGroup) {
defer wg.Done() // when work is done, declare termination
log.Printf("hello wait group %v\n", i)
}(i, &wg)
// Please add a stop condition !
}
wg.Wait() // prevent your main program to return until all goroutines have ended
但是在您的情况下,创建数千个 goroutine 似乎无济于事(您的可用 CPU 可能较少)。在这种情况下,您可以改用具有有限并发性的池。如果您愿意使用它,我为此编写了一个库:
import "github.com/aherve/gopool"
func main() {
pool := gopool.NewPool(8) // creates pool with limited concurrency of 8
for {
pool.Add(1)
go func(i int, pool *gopool.GoPool) {
defer pool.Done()
time.Sleep(time.Second)
log.Printf("hello pool %v\n", i)
}(i, pool)
// Please add a stop condition !
}
pool.Wait()
}
在这个版本中,不会超过 8 个例程同时启动,并且代码仍然与waitGroup
用法非常相似。
推荐阅读
- reactjs - 与 React、Expo 和 React-Navigation 的深度链接
- xml - 如何将节点的内部文本和 XML 提取为字符串?
- reactjs - 在 github 上安装 env-cmd
- sql - SQL 每个值的最大连续值数
- ruby-on-rails - 如何模拟会话登录来测试 Rails 控制器方法?
- powershell - 当从 Powershell Core 和 Powershell 5.1 运行脚本时,使用 export-csv 的 Powershell 输出会产生不同的结果
- mysql - 考虑通过将“EnableRetryOnFailure()”添加到“UseMySql”调用来启用瞬时错误恢复能力
- kubernetes - 使用 Quarkus 挂载 Kubernetes 卷
- swiftui - 如何在 SwiftUI 中正确使用动态成员绑定?
- java - 是否可以在另一个类中调用 @beforeclass 而无需在当前的 testng 类中扩展