在提供的代码中,目的是让主 goroutine 通过使用通道和通道来打印从 1 到 11 的数字。等组。但是,它偶尔会跳过数字 11,导致输出不完整。
问题是由于将sync.WaitGroup 错误地传递给外部函数Print 引起的。通过将 WaitGroup 的副本传递给函数,它无法对主 goroutine 正在等待的原始等待组执行必要的 Done() 调用。
最佳解决方案:
推荐的解决方案包括修改代码如下:
<code class="go">func main() { ch := make(chan int) var wg sync.WaitGroup wg.Add(2) go Print(ch, &wg) go func() { for i := 1; i <= 11; i++ { ch <- i } close(ch) defer wg.Done() }() wg.Wait() } func Print(ch <-chan int, wg *sync.WaitGroup) { for n := range ch { // reads from channel until it's closed fmt.Println(n) } defer wg.Done() }</code>
在此修复中,Print 函数接收指向等待组的指针,确保在
替代解决方案:
或者,可以通过直接关闭通道来消除 Print 函数中对 WaitGroup 的需要发送完所有数字后:
<code class="go">func Print(ch <-chan int) { for n := range ch { // reads from channel until it's closed fmt.Println(n) } }</code>
在这种情况下,主 Goroutine 必须等待通道关闭:
<code class="go">wg.Wait() close(ch)</code>
以上是为什么在外部函数中使用 Sync.WaitGroup 的副本会导致 goroutine 中输出丢失?的详细内容。更多信息请关注PHP中文网其他相关文章!