go - make(chan bool) 与 make(chan bool, 1) 的行为有何不同?

标签 go channel

我的问题来自尝试读取 channel ,如果可以的话,或者写它,如果可以的话,使用 select声明。

我知道像 make(chan bool, 1) 这样指定的 channel 被缓冲了,我的部分问题是它和 make(chan bool) 有什么区别? -- 其中this page说与 make(chan bool, 0) 相同--- 一个 channel 可以容纳 0 值的意义何在?

playground A :

chanFoo := make(chan bool)

for i := 0; i < 5; i++ {
    select {
    case <-chanFoo:
        fmt.Println("Read")
    case chanFoo <- true:
        fmt.Println("Write")
    default:
        fmt.Println("Neither")
    }
}

输出:

Neither
Neither
Neither
Neither
Neither

(删除 default 会导致死锁!!)

现在看 playground B :

chanFoo := make(chan bool, 1)   // the only difference is the buffer size of 1

for i := 0; i < 5; i++ {
    select {
    case <-chanFoo:
        fmt.Println("Read")
    case chanFoo <- true:
        fmt.Println("Write")
    default:
        fmt.Println("Neither")
    }
}

B 输出:

Write
Read
Write
Read
Write

就我而言,B 输出 是我想要的。无缓冲 channel 有什么好处?我在 golang.org 上看到的所有示例似乎都使用它们一次发送一个信号/值(这就是我所需要的)——但就像在 Playground A 中一样, channel 永远不会被读取书面。在我对 channel ​​的理解中,我在这里遗漏了什么?

最佳答案

what is the point of a channel that can fit 0 values in it

首先我要指出,这里的第二个参数是指缓冲区大小,所以这只是一个没有缓冲区的 channel (无缓冲 channel )。

其实这就是你的问题产生的原因。无缓冲 channel 仅在有人阻止读取时才可写,这意味着您将有一些协程可以使用——而不是单个协程。

另见 The Go Memory Model :

A receive from an unbuffered channel happens before the send on that channel completes.

关于go - make(chan bool) 与 make(chan bool, 1) 的行为有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20041392/

相关文章:

Go HTTP 请求超时

go - 合并两个关闭 channel

Go:嵌入类型在派生类型中的字段初始化

go - 我应该明确地创建一个与 "Belongs To"或 "Has Many"对称的关系吗?

go - 如何将参数传递给 Go 中的 alice 中间件?

go - PowerPC 版本的 Go

javascript - 使用 Channel API 接收来自任务队列中任务的消息

.net - WCF channel 故障状态是否有帮助?

go - 我如何向 channel 发送者发出信号以退出 golang?

logging - 如何在 Silex 中为 Monolog 设置不同的文件