我刚刚在使用通道在两个 goroutine 之间进行通信时遇到了死锁。
当我简单的把自己写的代码做起来测试的时候,两个goroutine就陷入了block状态,无法再通信了
func TestDeadLock(t *testing.T) {
pingChan := make(chan int)
pongChan := make(chan int)
go ping(pingChan, pongChan)
go pong(pongChan, pingChan)
pingChan <- 1
select {}
}
func ping(pingChan <-chan int, pongChan chan<- int) {
for {
ball := <-pingChan
log.Println("Ping", ball)
//time.Sleep(0)
pongChan <- ball + 1
}
}
func pong(pongChan <-chan int, pingChan chan<- int) {
for {
ball := <-pongChan
log.Println("Pong", ball)
//time.Sleep(0)
pingChan <- ball + 1
}
}
运行上述测试的结果是:
...
2023/03/23 16:46:36 Ping 1433
2023/03/23 16:46:36 Pong 1434
2023/03/23 16:46:36 Ping 1435
2023/03/23 16:46:36 Pong 1436
2023/03/23 16:46:36 Ping 1437
// nothing is output anymore
然而,我想实现两个goroutine之间的无限通信,在寻找这样的例子时,我发现了一个与我的测试代码完全相同的例子,但与我的测试代码不同的是,它输出了一个真正无限的值。
package main
import (
"log"
)
func main() {
pingChan := make(chan int)
pongChan := make(chan int)
go ping(pingChan, pongChan)
go pong(pongChan, pingChan)
pingChan <- 1
select {}
}
func ping(pingChan <-chan int, pongChan chan<- int) {
for {
ball := <-pingChan
log.Println("Ping", ball)
//time.Sleep(0)
pongChan <- ball + 1
}
}
func pong(pongChan <-chan int, pingChan chan<- int) {
for {
ball := <-pongChan
log.Println("Pong", ball)
//time.Sleep(0)
pingChan <- ball + 1
}
}
...
2023/03/23 16:46:22 Ping 3107391
2023/03/23 16:46:22 Pong 3107392
2023/03/23 16:46:22 Ping 3107393
2023/03/23 16:46:22 Pong 3107394
2023/03/23 16:46:22 Ping 3107395
2023/03/23 16:46:22 Pong 3107396
2023/03/23 16:46:22 Ping 3107397
2023/03/23 16:46:22 Pong 3107398
2023/03/23 16:46:22 Ping 3107399
...
即使洗了眼睛再看,也没有发现什么不同。唯一的区别是我创建的示例是测试函数,而我找到的示例是主函数。
这两个代码有什么区别,所以我的测试代码如期发生了死锁,下面的代码可以连续输出值?
如果我想两个goroutine之间无限通信不终止怎么办?