Golang中如何精确控制协程输出20个数字
Golang中如何精确控制协程输出20个数字 Go 协程在总计恰好 20 个数字后执行
4 回复
你可以使用一个计数器,所有 Go 协程都会递增它,以及一个互斥锁,Go 协程在递增计数器时会锁定和解锁它。如果计数器达到 20,Go 协程就直接返回。
这看起来相当晦涩难懂。
通常来说,我不会使用协程来打印数值,而是用它们来生成数值,然后在主函数中进行打印:
func main() {
fmt.Println("hello world")
}
在Go语言中,要精确控制协程输出恰好20个数字,可以使用sync.WaitGroup来同步协程的完成,并通过通道或互斥锁来确保计数的准确性。以下是一个示例,使用WaitGroup和带缓冲的通道来协调多个协程,确保总共输出20个数字:
package main
import (
"fmt"
"sync"
)
func main() {
const totalNumbers = 20
const numGoroutines = 4 // 使用4个协程来分发任务
var wg sync.WaitGroup
ch := make(chan int, totalNumbers) // 缓冲通道用于收集数字
// 启动生产者协程,每个协程负责生成部分数字
for i := 0; i < numGoroutines; i++ {
wg.Add(1)
go func(start int) {
defer wg.Done()
// 每个协程生成5个数字(总计20)
for j := 0; j < totalNumbers/numGoroutines; j++ {
num := start*(totalNumbers/numGoroutines) + j + 1
ch <- num
}
}(i)
}
// 等待所有生产者协程完成,然后关闭通道
go func() {
wg.Wait()
close(ch)
}()
// 在主协程中收集并输出数字
count := 0
for num := range ch {
fmt.Println(num)
count++
}
// 验证输出数字总数
fmt.Printf("总计输出数字数量: %d\n", count)
}
在这个示例中:
- 我们使用4个协程(
numGoroutines)来并行生成数字,每个协程负责5个数字,总计20个。 sync.WaitGroup用于等待所有生产者协程完成工作。- 带缓冲的通道
ch用于安全地传递数字,缓冲区大小设置为20以避免阻塞。 - 主协程通过循环从通道读取数字并输出,直到通道关闭。
- 最后输出计数以验证恰好20个数字。
运行此代码将输出数字1到20,每个数字一行,并在最后显示总数20。这种方法确保了协程间的同步和精确的数字计数。如果需要不同的数字分布或顺序,可以调整协程逻辑。


