golang频道是否基于LIFO?

时间:2018-08-12 07:49:27

标签: go channel fifo lifo

我想知道golang频道中元素的顺序。在运行了几个示例之后,元素从通道中离开的顺序似乎是“后进先出”。我说的对吗?

以下代码段是我使用的示例。运行代码后,输出为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)
}

1 个答案:

答案 0 :(得分:4)

Golang频道不是LIFO。

  

通道充当先进先出队列。例如,如果一个   goroutine在通道上发送值,第二个goroutine接收   它们,则按发送顺序接收值。

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

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

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)
  

容量(以元素数为单位)设置缓冲区的大小   这个频道。如果容量为零或不存在,则通道为   只有当发送者和   接收器已准备就绪。否则,通道将被缓冲,并且   如果缓冲区未满,则通信成功且没有阻塞   (发送)或不为空(接收)。零频道永远不会准备好   交流。

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

有关更多信息,请访问Golang Channels