golang 频道是基于 LIFO 的吗?

Are golang channels based on LIFO?

我想知道 golang 频道中元素的顺序。在 运行 几个例子之后,似乎元素离开通道的顺序是 "last in first out"。我说得对吗?

以下代码段是我使用的示例。在 运行 代码之后,输出为 20 10,而 10 首先发送到通道,最后发送 20。

package main

import "fmt"

func multiply(c chan int, num int) {
    c <- num * 10
}

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

    go multiply(c, 1)
    go multiply(c, 2)

    v1 := <-c
    v2 := <-c
    fmt.Println(v1, v2)
}

Golang 渠道不是后进先出。

Channels act as first-in-first-out queues. For example, if one goroutine sends values on a channel and a second goroutine receives them, the values are received in the order sent.

只要通道的接收器准备就绪,通道上发送的值就会被接收。如果没有,它就会阻塞。要管理它,您可以使用缓冲通道。

下面的代码将检查是否可以从通道接收值。

package main

import "fmt"

func multiply(c chan int, num int) {
    c <- num * 10
}

func main() {
    c := make(chan int, 3)

    go multiply(c, 1)
    go multiply(c, 2)
    go multiply(c, 3)

    for i:=0;i<3;i++{
         foo, ok := <- c
         if !ok {
                fmt.Println("done")
                return
         }
         fmt.Println(foo)
    }

}

Go playground

上的工作代码

缓冲通道

频道可以缓冲。提供缓冲区长度作为初始化缓冲通道的第二个参数:

make(chan int, 100)

The capacity, in number of elements, sets the size of the buffer in the channel. If the capacity is zero or absent, the channel is unbuffered and communication succeeds only when both a sender and receiver are ready. Otherwise, the channel is buffered and communication succeeds without blocking if the buffer is not full (sends) or not empty (receives). A nil channel is never ready for communication.

在您的情况下,这取决于哪个 go 例程将首先在通道上发送值。您打印的值完全取决于 go 例程。

有关详细信息,请访问 Golang Channels