由于按值传递结构导致 Go 通道通信死锁
在您的代码中,您在 goroutine 通道中遇到了死锁错误沟通。此错误是因为您将 WaitGroup 结构按值传递给 goroutine,这会创建 WaitGroup 的副本,而不是共享原始引用。
为什么按值传递会导致死锁
Go 中的结构体是按值传递的,而不是按引用传递的。当您将结构传递给函数时,会创建一个副本并将其传递给该函数。这意味着对函数内结构所做的任何更改都不会反映在函数外部的原始结构中。
在您的情况下,goroutine 在完成任务时会尝试向 WaitGroup 发出信号。但是,由于他们使用 WaitGroup 的副本,因此他们的 Done() 调用不会影响原始 WaitGroup。因此,主协程中的 Wait() 调用永远不会完成,从而导致死锁。
解决方案:通过指针传递
要解决此问题,您可以需要通过指针将 WaitGroup 传递给您的 goroutine。这确保了 goroutine 和主 goroutine 共享对 WaitGroup 的相同引用。
工作示例:
这是代码的正确版本:
<code class="go">package main import ( "fmt" "sync" ) func push(c chan int, wg *sync.WaitGroup) { for i := 0; i < 5; i++ { c <- i } wg.Done() } func pull(c chan int, wg *sync.WaitGroup) { for i := 0; i < 5; i++ { result, ok := <-c fmt.Println(result, ok) } wg.Done() } func main() { var wg sync.WaitGroup wg.Add(2) c := make(chan int) go push(c, &wg) go pull(c, &wg) wg.Wait() }</code>
现在,当您运行此代码时,您应该不再遇到死锁错误。 goroutine 将成功向 WaitGroup 发出信号,主 goroutine 将能够完成其执行。
以上是为什么按值传递 WaitGroup 结构会导致 Go Channel 通信死锁?的详细内容。更多信息请关注PHP中文网其他相关文章!