在 Go 中,我预计会发生死锁,但事实并非如此

问题描述 投票:0回答:0

我刚刚在使用通道在两个 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之间无限通信不终止怎么办?

go deadlock channel goroutine
© www.soinside.com 2019 - 2024. All rights reserved.