第一份代码如下
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
}
|      10o0O0o0O0o      2023-07-06 08:44:51 +08:00 via iPhone 第一份代码也是有 panic 的潜力的,建议读 https://tour.go-zh.org/concurrency/2 | 
|      2aarontian      2023-07-06 08:45:29 +08:00 via Android 所有线程都阻塞就 panic 了 | 
|  |      3rekulas      2023-07-06 08:48:14 +08:00 第二个没有运行中的协程,编译器直接判断死锁了,随便加一个就可以了 | 
|  |      4rekulas      2023-07-06 08:49:45 +08:00 说错 不是编译器判断 是运行中判断的 | 
|  |      5Rooger      2023-07-06 09:01:27 +08:00 能写出第二个代码,有一个基本的原则你没有弄明白。即 channel 的用途:在不同的协程之间进行消耗的传递,而第二份代码,即对 channel 没有初始化,也没有额外的协程存在。 | 
|      60o0O0o0O0o      2023-07-06 09:17:17 +08:00 @0o0O0o0O0o #1 emmm 抱歉看错了 | 
|      7Seanfuck      2023-07-06 09:24:10 +08:00 chan 不是要 make 来创建吗,var **也行? | 
|  |      88355      2023-07-06 09:29:40 +08:00 第二个没懂先看基础文档吧。。。。。 | 
|      9paceewang1      2023-07-06 09:48:52 +08:00 @Seanfuck var 是声明 | 
|  |      10hsfzxjy      2023-07-06 09:59:00 +08:00 via Android 所有 goroutine 都睡了就会 panic | 
|      11CarrieBauch OP @aarontian  明白了,panic 会发生在所有的协程都被阻塞的情况下。把第一个程序简化为这样之后,也不会 panic 。因为 go 启动的一个协程在不断的运行,所以不会 panic package main func main() { go func() { for { } }() var c chan bool <-c } | 
|      12CarrieBauch OP @rekulas  明白了,多谢多谢 | 
|      13CarrieBauch OP @hsfzxjy 感谢感谢 | 
|  |      14Richard14      2023-07-06 10:15:56 +08:00 我看 op 的贴,把第二段代码加了个放东西的协程,感觉就不会出错了,然而还是报错,OP 知道啥原因吗? package main import ( "fmt" ) func main() { var c chan bool go func() { c <- true }() fmt.Println(<-c) } | 
|      16CarrieBauch OP  1 @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) } | 
|  |      17lasuar      2023-07-06 10:45:20 +08:00 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 并退出。 | 
|      18crescentBLADE      2023-07-06 10:48:30 +08:00 @Richard14 把 “var c chan bool”  改成 “var c = make(chan bool)”就可以了,未初始化的 chan 变量并没有分配任何内存空间,因此无法进行读写操作 | 
|  |      19codehz      2023-07-06 13:40:50 +08:00 import 一个"net"也不会 panic🤣🤣🤣 | 
|      20BinaryDH      2023-07-06 17:47:57 +08:00 唉,问了一个问题,还得到了一份错误的答案!好好看看 channel 和 groutine 的文档吧,每一次阅读和编写 demo ,相信你都能有不同的提升。 | 
|      21CarrieBauch OP @BinaryDH 求明说,或者给一个去验证的方向 |