go 发生死锁的问题

liu826250634 · · 933 次点击
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() defer close(jobChan) 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) } go func() { for i := range resultChan { fmt.Println(i) } }() wg.Wait() }
#4
更多评论
为什么会发生死锁的问题? * jobChan在数据生产结束之后没有关闭 * resultChan 没有额外再起协程去消费 以上两点造成: * 当jobChan没有新数据往里面放的时候,**for i := 0; i < 24; i++** 这一行起的24个协程一直在等待新数据到来,一直在***for num := range jobChan **处等待,阻塞了 * 主函数里面的**for i:= range resultChan** 也一直在等待resultChan的数据,阻塞了。 * 到这里,所有的协程都阻塞,然后就出现了 **fatal error: all goroutines are asleep - deadlock! **.. 要想解决这个问题,可以按照以下修改 ```golang 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) } // **关闭channel** close(jobChan) }(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) } // **再起一个协程去消费channel** go func() { for i := range resultChan { fmt.Printf("%d\n", i) } }() time.Sleep(10 * time.Second) fmt.Print("\n\nend...\n\n") wg.Wait() } ```
#1
* [Go 语言中通道死锁经典错误案例详解][1] [1]: https://studygolang.com/articles/29077#reply0
#2