
第一份代码如下
package main import ( "fmt" "time" ) func main() { var ball = make(chan string) kickBall := func(playerName string) { for { fmt.Print(<-ball, "传球", "\n") time.Sleep(1 * time.Second) ball <- playerName } } go kickBall("张三") go kickBall("李四") go kickBall("王五") go kickBall("赵六") ball <- "裁判" var c chan bool <-c } 分界线
第二份代码如下
package main func main() { var c chan bool <-c } 1 0o0O0o0O0o Jul 6, 2023 via iPhone 第一份代码也是有 panic 的潜力的,建议读 https://tour.go-zh.org/concurrency/2 |
2 aarontian Jul 6, 2023 via Android 所有线程都阻塞就 panic 了 |
3 rekulas Jul 6, 2023 第二个没有运行中的协程,编译器直接判断死锁了,随便加一个就可以了 |
4 rekulas Jul 6, 2023 说错 不是编译器判断 是运行中判断的 |
5 Rooger Jul 6, 2023 能写出第二个代码,有一个基本的原则你没有弄明白。即 channel 的用途:在不同的协程之间进行消耗的传递,而第二份代码,即对 channel 没有初始化,也没有额外的协程存在。 |
6 0o0O0o0O0o Jul 6, 2023 @0o0O0o0O0o #1 emmm 抱歉看错了 |
7 Seanfuck Jul 6, 2023 chan 不是要 make 来创建吗,var **也行? |
8 8355 Jul 6, 2023 第二个没懂先看基础文档吧。。。。。 |
9 paceewang1 Jul 6, 2023 @Seanfuck var 是声明 |
10 hsfzxjy Jul 6, 2023 via Android 所有 goroutine 都睡了就会 panic |
11 CarrieBauch OP @aarontian 明白了,panic 会发生在所有的协程都被阻塞的情况下。把第一个程序简化为这样之后,也不会 panic 。因为 go 启动的一个协程在不断的运行,所以不会 panic package main func main() { go func() { for { } }() var c chan bool <-c } |
12 CarrieBauch OP @rekulas 明白了,多谢多谢 |
13 CarrieBauch OP @hsfzxjy 感谢感谢 |
14 Richard14 Jul 6, 2023 我看 op 的贴,把第二段代码加了个放东西的协程,感觉就不会出错了,然而还是报错,OP 知道啥原因吗? package main import ( "fmt" ) func main() { var c chan bool go func() { c <- true }() fmt.Println(<-c) } |
16 CarrieBauch OP @Richard14 你把代码改成这样,就不会 panic 了 原因就是 channel 没有初始化,只是做了 var 的声明 package main import ( "fmt" ) func main() { //var c chan bool c := make(chan bool) go func() { c <- true }() fmt.Println(<-c) } |
17 freemoon Jul 6, 2023 go 允许对一个 nil chan 进行读操作,这会导致阻塞。第二个例子会监测到死锁 panic 的原因是程序中没有其他 goroutine 正在运行。值得说明的是,这里不仅仅是要求有其他 goroutine 在运行,而且也不能全部同时阻塞,此时 go 运行时会监测到程序无法解除阻塞状态,从而再次导致死锁 panic 。 下面的代码说明了 [其他 goroutine 不能全部同时阻塞的情况] : ``` go func() { var cc = make(chan bool) <-cc }() var c = make(chan bool) <-c ``` 最后:通过第二段代码(无论 chan 是否通过 make 创建)来阻塞主程序不是合理的实践,原因上面说了,当程序中只剩下一个 goroutine (主)在运行时,这种代码会死锁 panic 并退出。 |
18 crescentBLADE Jul 6, 2023 @Richard14 把 “var c chan bool” 改成 “var c = make(chan bool)”就可以了,未初始化的 chan 变量并没有分配任何内存空间,因此无法进行读写操作 |
19 codehz Jul 6, 2023 import 一个"net"也不会 panic |
20 BinaryDH Jul 6, 2023 唉,问了一个问题,还得到了一份错误的答案!好好看看 channel 和 groutine 的文档吧,每一次阅读和编写 demo ,相信你都能有不同的提升。 |
21 CarrieBauch OP @BinaryDH 求明说,或者给一个去验证的方向 |