dongwo7858 2011-05-12 19:40
浏览 48
已采纳

进入频道并陷入僵局

I'm trying to understand the Go language. I tried to create two goroutines that chain the flow between them using two channels:

func main() {
c1 := make(chan int)
c2 := make(chan int)

go func() {
    for i := range c1{
        println("G1 got", i)
        c2 <- i
    }
}()

go func() {
    for i := range c2 {
        println("G2 got", i)
        c1 <- i
    }
}()


c1 <- 1

time.Sleep(1000000000 * 50)
}

As expected this code prints:

 G1 got 1
 G2 got 1
 G1 got 1
 G2 got 1
 ....

Until the main function exits.

But if I send another value to one of the channels from main, it suddenly blocks:

func main() {
c1 := make(chan int)
c2 := make(chan int)

go func() {
    for i := range c1{
        println("G1 got", i)
        c2 <- i
    }
}()

go func() {
    for i := range c2 {
        println("G2 got", i)
        c1 <- i
    }
}()


c1 <- 1

time.Sleep(1000000000 * 1)

c1 <- 2

time.Sleep(1000000000 * 50)
}

It outputs

G1 got 1
G2 got 1
G1 got 1
G2 got 1
G1 got 2

and then blocks until the main ends.

The value "2" sent to c1 arrives to the first goroutie, which sends it to c2, but the second goroutine never receives.

(Using buffered channels with size 1 (either c1 or c2) works in this example)

Why does it happen? When this happens in real code, how can I debug it?

  • 写回答

2条回答 默认 最新

  • duan1226 2011-05-12 19:43
    关注

    Go channels created with make(chan int) are not buffered. If you want a buffered channel (that won't necessarily block), make it with make(chan int, 2) where 2 is the size of the channel.

    The thing about unbuffered channels is that they are also synchronous, so they always block on write as well as read.

    The reason it deadlocks is that your first goroutine is waiting for its c2 <- i to finish while the second one is waiting for c1 <- i to finish, because there was an extra thing in c1. The best way I've found to debug this sort of thing when it happens in real code is to look at what goroutines are blocked and think hard.

    You can also sidestep the problem by only using synchronous channels if they're really needed.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥23 (标签-bug|关键词-密码错误加密)
  • ¥66 比特币地址如何生成taproot地址
  • ¥20 数学建模数学建模需要
  • ¥15 关于#lua#的问题,请各位专家解答!
  • ¥15 什么设备可以研究OFDM的60GHz毫米波信道模型
  • ¥15 不知道是该怎么引用多个函数片段
  • ¥30 关于用python写支付宝扫码付异步通知收不到的问题
  • ¥15 隐藏系统界面pdf的打印、下载按钮
  • ¥15 基于pso参数优化的LightGBM分类模型
  • ¥15 安装Paddleocr时报错无法解决