dow46218 2017-07-28 07:05
浏览 45
已采纳

golang通道与make相关的死锁

I'm new to Golang and meet the strange behavior of Go's channel. The question is described as the following.

package main

import "fmt"

func main() {
    ch := make(chan int)

    fmt.Println("len:", len(ch))
    fmt.Println("cap:", cap(ch))
    fmt.Println("is nil:", ch == nil)

    go func(ch chan int){
        ch <- 233
    }(ch)

    fmt.Println(<- ch)

}

When I run the code above, I got result like this:

len: 0
cap: 0
is nil: false
233

The len and cap of the channel ch seem wierd but the code still works. But when I run this code:

package main

import "fmt"

func main() {
    ch := make(chan int)

    fmt.Println("len:", len(ch))
    fmt.Println("cap:", cap(ch))
    fmt.Println("is nil:", ch == nil)

    ch <- 233 // Here changes!

    fmt.Println(<- ch)

}

The result became: len: 0 cap: 0 is nil: false fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
    /tmp/sandbox640280398/main.go:12 +0x340

What's more, when I change the second code piece like the following: package main

import "fmt"

func main() {
    ch := make(chan int, 1) //Here changes!

    fmt.Println("len:", len(ch))
    fmt.Println("cap:", cap(ch))
    fmt.Println("is nil:", ch == nil)

    ch <- 233

    fmt.Println(<- ch)

}

Things worked again, I got:

len: 0
cap: 1
is nil: false
233

So, can anybody tell me the following questions:

  1. Why make(chan int) return a channel with zero len and zero cap but still can work well in first code piece?

  2. Why the second code use the channel in the main function instead of a new goroutine cause the deadlock?

  3. Why I add a cap parameter to make in third code can fix the problem?

  4. What's the difference between the channel(in 1st and 2nd code) with the nil channel?

Thanks!

  • 写回答

1条回答 默认 最新

  • dongxian8858 2017-07-28 07:48
    关注

    You can create two types of channels: buffered channels and unbuffered channels.
    Buffered channel are those that has capacity: make(chan int, 10)
    Buffered channels allow you to send into them same amount of messages as their capacity without being blocked.
    Unbuffered channels has no capacity and that is why your sending goroutine will be blocked until another goroutine receive from it.

    1. It is unbuffered channel. You main goroutine is blocked on receiving from channel until new goroutine send message to it.

    2. Because you are using unbuffered channel your sending goroutine is blocked until another receive from it, but you have no other goroutines except that main one, so the program is in deadlock.

    3. Because of buffered goroutine. It has capacity of 1, so it is won't be problem to send one message to it and then receive it in the same goroutine. But you will be blocked if you try to send more than 1 message to it. ch <- 233; ch <- 233 - this code will cause a deadlock.

    4. Did get what you mean..., but if you try to receive or send to a nil channel you will be blocked: var ch chan int; <-ch or var ch chan int; ch <- 1

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 linux驱动,linux应用,多线程
  • ¥20 我要一个分身加定位两个功能的安卓app
  • ¥15 基于FOC驱动器,如何实现卡丁车下坡无阻力的遛坡的效果
  • ¥15 IAR程序莫名变量多重定义
  • ¥15 (标签-UDP|关键词-client)
  • ¥15 关于库卡officelite无法与虚拟机通讯的问题
  • ¥15 目标检测项目无法读取视频
  • ¥15 GEO datasets中基因芯片数据仅仅提供了normalized signal如何进行差异分析
  • ¥100 求采集电商背景音乐的方法
  • ¥15 数学建模竞赛求指导帮助