按道理 main 结束之前启动的 goroutine 不会结束,如果不发送 stopCh ,则会一直阻塞,为啥会提示有死锁
package main
import (
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
fmt.Print("hello world\n")
ch1 := make(chan int)
ch2 := make(chan int)
stopCh := make(chan struct{})
wg.Add(1)
go work(ch1, ch2, stopCh)
ch1 <- 1
ch2 <- 1
time.Sleep(1000 * time.Millisecond)
// stopCh <- struct{}{}
var a int
wg.Wait()
fmt.Scan(&a)
}
func work(ch1, ch2 chan int, stopCh <-chan struct{}) {
defer wg.Done()
for {
select {
case <-stopCh:
return
case job1 := <-ch1:
fmt.Println("receive ch1 on first loop:", job1)
case job2 := <-ch2:
priority:
for {
select {
case job1 := <-ch1:
fmt.Println("receive ch1 on second loop:", job1)
default:
time.Sleep(1000 * time.Millisecond)
break priority
}
}
// 执行 job1 的内容
fmt.Println("receive ch2:", job2)
}
}
}
运行之后报错
hello world
receive ch1 on first loop: 1
receive ch2: 1
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xd77c28)
C:/go/src/runtime/sema.go:56 +0x49
sync.(*WaitGroup).Wait(0xd77c20)
C:/go/src/sync/waitgroup.go:130 +0x6b
main.main()
F:/code/go/c2c/client/client.go:24 +0x1b6
goroutine 6 [select]:
main.work(0xc000014180, 0xc0000141e0, 0xc000014240)
F:/code/go/c2c/client/client.go:30 +0x26e
created by main.main
F:/code/go/c2c/client/client.go:17 +0x146
exit status 2
1
quzard 2022-02-11 00:32:53 +08:00 via Android
你的 work 被阻塞休眠了。然后导致已有的 goroutine 都处于休眠状态,导致报错了
|
2
quzard 2022-02-11 00:35:15 +08:00 via Android
WaitGroup 永远不会被通知 done ,造成了异常
|
3
lianyue 2022-02-11 00:36:43 +08:00
进了
job2 := <-ch2 就不能退出了 永远都在里面 |
4
CEBBCAT 2022-02-11 00:50:24 +08:00
楼主的第一句话看得不是很懂,work 的第一个 for 也没看见能主动退出的地方啊
|
5
ch2 2022-02-11 01:46:43 +08:00 via iPhone
建议先把名字取好,没人愿意看一堆 c1 、c2 不知干啥用的变量名
|
6
lovelylain 2022-02-11 08:19:35 +08:00 via Android
stopCh <- struct{}{}被你注释了,main 阻塞在 wg.Wait(),work 阻塞在 select ,没其他 goroutine 在活动能改变这俩阻塞状态。
|
7
awalkingman 2022-02-11 09:42:24 +08:00 2
@ch2 你这昵称很应景哈哈哈哈哈
|
8
proxytoworld OP @CEBBCAT 在里面有 return 这个协程会退出 如果收到 stopCh
|
9
proxytoworld OP @ch2 测试用例 所以没取名
|
10
proxytoworld OP @jobmailcn 懂了
|
11
CEBBCAT 2022-02-14 12:58:04 +08:00
推荐楼主学习一下《银行家算法》
|