维持固定数量的并发 Goroutine
在 Go 中,你可能会遇到控制并发运行的 Goroutine 数量至关重要的场景。虽然教程通常侧重于等待 goroutine 完成,但在任何给定时间实现特定数量的活动 goroutine 会带来不同的挑战。
考虑以下情况:您有数十万个任务需要处理。处理每个任务都需要有自己的 Goroutine,但是您的系统资源最多只能处理 20 个并发 Goroutine。您需要确保始终有 20 个 goroutine 运行,只要现有的 goroutine 完成,就启动一个新的 goroutine。
有界并行
为了实现这一目标,Go 并发模式文章建议使用一种称为“有限并行”的模式。它涉及使用空结构体通道作为保护来限制并发工作线程的数量。
实现
以下示例演示了如何实现此模式:
package main import ( "fmt" "sync" ) func main() { const maxGoroutines = 20 // Create a channel of empty structs to control worker count guard := make(chan struct{}, maxGoroutines) var wg sync.WaitGroup // Launch workers for i := 0; i < 30; i++ { wg.Add(1) guard <- struct{}{} // Blocks if guard channel is filled go func(n int) { defer wg.Done() worker(n) <-guard // Release slot in guard channel }(i) } wg.Wait() } func worker(i int) { fmt.Println("doing work on", i) }
在这个例子中,保护通道被用作令牌桶。可以同时运行的 Goroutine 的最大数量受到通道容量的限制(本例中为 20)。每个 goroutine 在开始工作之前都会从通道获取一个“令牌”(一个空结构)。当一个 goroutine 完成时,它将其令牌释放回通道,使其可供另一个 goroutine 获取。通过控制通道中 token 的数量,可以有效控制并发 goroutine 的数量。
以上是Go中如何保持固定数量的并发Goroutine?的详细内容。更多信息请关注PHP中文网其他相关文章!