本文介绍了Go中的频道死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 限时删除!! 出于某种原因,在下面的代码中,我得到了致命错误:所有goroutines都睡着了 - 死锁!。我正在使用应该是非阻塞的缓冲通道。不知道我在做什么错误 package main import(fmt sync) func main(){c:= make(chan int,2) var wg sync.WaitGroup wg.Add(2) go doSomething(c,wg) go doSomething(c,wg) go doSomething(c,wg) wg.Wait() close(c) for v:= range c { fmt.Print(v)} $ b func doSomething(c chan< - int,wg sync.WaitGroup){ defer wg.Done()c< - 1 } Playground link https://play.golang.org/p/J9meD5aKna 解决方案 首先,您需要更改频道大小以使其成为可能工作表明存在潜在的问题/错误。现在,每次您想要启动另一个 doSomething 时,您都必须记住更改频道的长度。第二,等待直到所有的goroutines在完成通道读取之前完成。这是一种浪费,因为频道范围循环的一个要点是您不必等到所有项目都生成(写入频道),您可以尽快开始处理项目他们准备好了。 所以我会把你的代码写成类似于 c:= make(chan int) var wg sync.WaitGroup wg.Add(3) go func { doSomething(c)推迟wg.Done()}()去func(){ doSomething(c)延迟wg。完成()}() go func(){ doSomething(c) defer wg.Done()}() 去func(){ wg.Wait()延期关闭(c)}() for v:= range c { b fmt.Print(v)} } func doSomething(c chan c } https://play.golang.org/p/T3dfiztKot 请注意等待和关闭频道现在在它自己的goroutine中 - 这允许马上开始迭代频道(现在不缓冲!)。 我也改变了代码,这样 WaitGroup 永远不会离开声明的范围(即它不被用作参数),这是我的个人偏好。我相信它使代码更容易遵循和理解。 I am getting "fatal error: all goroutines are asleep - deadlock!" for some reason in the below code. I am using buffered channel which should be non-blocking. Not sure what I am doing wrongpackage mainimport ( "fmt" "sync")func main() { c := make(chan int, 2) var wg sync.WaitGroup wg.Add(2) go doSomething(c, wg) go doSomething(c, wg) go doSomething(c, wg) wg.Wait() close(c) for v := range c { fmt.Print(v) }}func doSomething(c chan<- int, wg sync.WaitGroup) { defer wg.Done() c <- 1}Playground link https://play.golang.org/p/J9meD5aKna 解决方案 While your solution might work I'm not happy with it.First, the fact that you need to change the channel size to make it work indicates that there is a potential problem / bug. Now each time you want to launch another doSomething you have to remember to change channel's length.Second, you wait until all the goroutines are finished before reading from the channel. This is kind of "waste" as one of the main points of range loop over an channel is that you don't have to wait until all the items are generated (written into channel), you can start processing the items as soon as some of them are ready.So I would write your code as something likefunc main() { c := make(chan int) var wg sync.WaitGroup wg.Add(3) go func() { doSomething(c) defer wg.Done() }() go func() { doSomething(c) defer wg.Done() }() go func() { doSomething(c) defer wg.Done() }() go func() { wg.Wait() defer close(c) }() for v := range c { fmt.Print(v) }}func doSomething(c chan<- int) { c <- 1}https://play.golang.org/p/T3dfiztKotNote how the waiting and closing the channel is now in it's own goroutine - this allows to start iterating over the channel (which is now unbuffered!) right away.I also changed the code so that the WaitGroup never leaves the scope where it is declared (ie it isn't used as parameter), this is my personal preference. I believe it makes code easier to follow and understand. 这篇关于Go中的频道死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 1403页,肝出来的..
09-08 06:00