golang: 所有的 goroutine 都处于休眠状态 – 死锁

huangapple go评论124阅读模式
英文:

golang: all goroutines are asleep - deadlock

问题

我想使用两个goroutine打印1到100:

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. var my_chan chan int
  7. var wg sync.WaitGroup
  8. func worker() {
  9. for true {
  10. number := <-my_chan
  11. fmt.Println(number)
  12. number++
  13. if number > 100 {
  14. wg.Done()
  15. return
  16. }
  17. my_chan <- number
  18. }
  19. }
  20. func main() {
  21. wg.Add(2)
  22. my_chan := make(chan int)
  23. init_num := 1
  24. go worker()
  25. go worker()
  26. my_chan <- init_num
  27. wg.Wait()
  28. }

当我运行上述代码时,我得到以下错误:

  1. fatal error: all goroutines are asleep - deadlock!

有人能告诉我我做错了什么吗?

英文:

I want to print 1 to 100 use two goroutine:

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;sync&quot;
  5. )
  6. var my_chan chan int
  7. var wg sync.WaitGroup
  8. func worker() {
  9. for true {
  10. number := &lt;-my_chan
  11. fmt.Println(number)
  12. number++
  13. if number &gt; 100 {
  14. wg.Done()
  15. return
  16. }
  17. my_chan &lt;- number
  18. }
  19. }
  20. func main() {
  21. wg.Add(2)
  22. my_chan := make(chan int)
  23. init_num := 1
  24. go worker()
  25. go worker()
  26. my_chan &lt;- init_num
  27. wg.Wait()
  28. }

When I run the above code, I get the following error:

  1. fatal error: all goroutines are asleep - deadlock!

Can anyone tell me where I am doing wrong?

答案1

得分: 2

将通道的创建替换为以下代码:

  1. my_chan := make(chan int)

否则,在主函数中重新声明my_chan,并且所有的goroutine都会尝试从一个空通道中读取。这将导致阻塞。

然后它将计数到100并发生死锁。对于其中一个goroutine,检查数字是否大于100将起作用,而另一个goroutine将被阻塞等待读取/写入操作。

英文:

Replace the channel creation with this:

  1. my_chan = make(chan int)

Otherwise you are redeclaring my_chan in main, and all goroutines try to read from a nil channel. That will block.

Then it will count to 100 and deadlock. The check for number being larger than 100 will work for one of the goroutines, while the other one will be stuck waiting to read/write.

答案2

得分: 0

感谢Burak Serdar的答案,以下代码有效:

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. var my_chan chan int
  7. var wg sync.WaitGroup
  8. func worker() {
  9. for true {
  10. number := <-my_chan
  11. if number > 100 {
  12. wg.Done()
  13. my_chan <- 101
  14. return
  15. }
  16. fmt.Println(number)
  17. number++
  18. my_chan <- number
  19. }
  20. }
  21. func main() {
  22. wg.Add(2)
  23. my_chan = make(chan int)
  24. init_num := 1
  25. go worker()
  26. go worker()
  27. my_chan <- init_num
  28. wg.Wait()
  29. }
英文:

Thanks for Burak Serdar's answer, the following code works:

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;sync&quot;
  5. )
  6. var my_chan chan int
  7. var wg sync.WaitGroup
  8. func worker() {
  9. for true {
  10. number := &lt;-my_chan
  11. if number &gt; 100 {
  12. wg.Done()
  13. my_chan &lt;- 101
  14. return
  15. }
  16. fmt.Println(number)
  17. number++
  18. my_chan &lt;- number
  19. }
  20. }
  21. func main() {
  22. wg.Add(2)
  23. my_chan = make(chan int)
  24. init_num := 1
  25. go worker()
  26. go worker()
  27. my_chan &lt;- init_num
  28. wg.Wait()
  29. }

huangapple
  • 本文由 发表于 2022年9月5日 22:55:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/73611249.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定