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 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?