与make

时间:2017-07-28 07:05:17

标签: go channel

我是Golang的新手并且遇到了Go频道的奇怪行为。问题描述如下。

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)

}

当我运行上面的代码时,我得到了这样的结果:

len: 0
cap: 0
is nil: false
233

ch 频道的 len 上限似乎很奇怪但代码仍然有效。但是当我运行这段代码时:

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)

}

结果变为:     len:0     上限:0     是零:假     致命错误:所有goroutines都睡着了 - 死锁!

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

更重要的是,当我更改第二个代码片段时,如下所示:     包主要

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)

}

事情再次奏效,我得到了:

len: 0
cap: 1
is nil: false
233

那么,任何人都可以告诉我以下问题:

  1. 为什么 make(chan int)会返回一个 len和上限的频道,但仍可在第一段代码中正常使用片

  2. 为什么第二个代码使用主函数中的而不是新的goroutine 导致死锁?

  3. 为什么我在第三段代码中为 make 添加上限参数可以解决问题?

  4. 渠道(第一和第二代码)与零渠道有什么区别?

  5. 谢谢!

1 个答案:

答案 0 :(得分:2)

您可以创建两种类型的频道:缓冲频道和无缓冲频道 缓冲通道是具有容量的通道:make(chan int, 10)
缓冲通道允许您向其发送与其容量相同数量的消息,而不会被阻止 无缓冲的频道没有容量,这就是为什么你的发送goroutine将被阻止,直到另一个goroutine从它接收。

1。这是无缓冲的频道。你从主频道接收主要goroutine被阻止,直到新的goroutine向它发送消息。

2。因为您使用的是无缓冲通道,所以发送goroutine会被阻止,直到另一个接收它,但除了主要通道外,您没有其他goroutine,因此程序处于死锁状态。

3。由于缓冲的goroutine。它的容量为1,因此向它发送一条消息然后在同一个goroutine中接收它就不会有问题。但是,如果您尝试向其发送多条消息,则会被阻止。 ch <- 233; ch <- 233 - 此代码将导致死锁。

4。得到了你的意思......但是如果你试图接收或发送到nil频道,你将被屏蔽:var ch chan int; <-chvar ch chan int; ch <- 1 < / p>