1. 首页
  2. 主题
  3. Go语言

go 发生死锁的问题

liu826250634 · · 1261 次点击
``` package main import ( "fmt" "math/rand" "sync" "time" ) var wg sync.WaitGroup //计算一个64位随机数的各位的和 func randNumber(x int64) int64 { var sum int64 = 0 for x > 0 { a := x % 10 x = x / 10 sum += a } return sum } func main() { wg.Add(25) var jobChan = make(chan int64, 10) var resultChan = make(chan int64, 10) go func(jobChan chan<- int64, ) { defer wg.Done() for i:=0;i<1000;i++{ rand.Seed(time.Now().UnixNano()) jobChan <- rand.Int63n(100) } }(jobChan) for i:=0;i<24;i++{ go func(jobChan <-chan int64, resultChan chan<- int64, ) { defer wg.Done() for num:= range jobChan{ resultChan <- randNumber(num) } }(jobChan, resultChan) } for i:= range resultChan{ fmt.Println(i) } wg.Wait() } ``` 发生错误:fatal error: all goroutines are asleep - deadlock! 请问为什么会发生死锁的问题
* [Go 语言中通道死锁经典错误案例详解][1] [1]: https://studygolang.com/articles/29077#reply0
#2
更多评论
为什么会发生死锁的问题? * jobChan在数据生产结束之后没有关闭 * resultChan 没有额外再起协程去消费 以上两点造成: * 当jobChan没有新数据往里面放的时候,**for i := 0; i &lt; 24; i++** 这一行起的24个协程一直在等待新数据到来,一直在***for num := range jobChan **处等待,阻塞了 * 主函数里面的**for i:= range resultChan** 也一直在等待resultChan的数据,阻塞了。 * 到这里,所有的协程都阻塞,然后就出现了 **fatal error: all goroutines are asleep - deadlock! **.. 要想解决这个问题,可以按照以下修改 ```golang package main import ( &#34;fmt&#34; &#34;math/rand&#34; &#34;sync&#34; &#34;time&#34; ) var wg sync.WaitGroup //计算一个64位随机数的各位的和 func randNumber(x int64) int64 { var sum int64 = 0 for x &gt; 0 { a := x % 10 x = x / 10 sum += a } return sum } func main() { wg.Add(25) var jobChan = make(chan int64, 10) var resultChan = make(chan int64, 10) go func(jobChan chan&lt;- int64) { defer wg.Done() for i := 0; i &lt; 1000; i++ { rand.Seed(time.Now().UnixNano()) jobChan &lt;- rand.Int63n(100) } // **关闭channel** close(jobChan) }(jobChan) for i := 0; i &lt; 24; i++ { go func(jobChan &lt;-chan int64, resultChan chan&lt;- int64) { defer wg.Done() for num := range jobChan { resultChan &lt;- randNumber(num) } }(jobChan, resultChan) } // **再起一个协程去消费channel** go func() { for i := range resultChan { fmt.Printf(&#34;%d\n&#34;, i) } }() time.Sleep(10 * time.Second) fmt.Print(&#34;\n\nend...\n\n&#34;) wg.Wait() } ```
#1
for num:= range jobChan{ resultChan &lt;- randNumber(num) } 这个循环退出不了
#3

用户登录

没有账号?注册

今日阅读排行

    加载中

一周阅读排行

    加载中