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条)

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度