doulei3488 2016-05-04 15:50
浏览 257

golang fifo缓冲通道

from my understanding: buffered channels in GO are not FIFO when the channel is full.
I need this behaviour in my application (FIFO behaviour).
How can I achieve that behaviour? Is there any open source for that?
Thanks in advance

EDIT:
some people disliked the question so let me be more clear:
I meant that when a buffered channel is full and multiple senders are blocked
while trying to add items to the channel the order in which they'll be released
is not FIFO. You can also read this discussion: https://github.com/golang/go/issues/11506

So yeah, I was looking for a third party library that implements that behaviour.
Sorry for not being clear.

  • 写回答

1条回答 默认 最新

  • dongye4192 2016-05-04 16:05
    关注

    Buffered channels in Go are always FIFO. The specification clearly says:

    Channels act as first-in-first-out queues.

    If the values coming out of the channel are not FIFO, then this is a bug in the channel implementation.

    The following code should always print 1, 2, 3, 4 in this correct order:

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        ch := make(chan int, 3)
        ch <- 1
        ch <- 2
        ch <- 3
    
        go func() {
            ch <- 4
        }()
    
        time.Sleep(time.Second)
    
        for i := 0; i < 4; i++ {
            fmt.Println(<-ch)
        }
    }
    

    Playground link

    Please note, that there is no guaruantee which value will be send first when there are multiple concurrent senders. If there are multiple waiting senders and someone removes one element from the channel buffer (or in the case of an unbuffered channel, tries to receive from the channel) the runtime will randomly choose one of the sending goroutines.

    Example:

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        ch := make(chan int, 2)
        ch <- 1
    
        go func() {
            ch <- 2
        }()
    
        go func() {
            ch <- 3
        }()
    
        time.Sleep(time.Second)
    
        for i := 0; i < 3; i++ {
            fmt.Println(<-ch)
        }
    }
    

    Playground link

    If you run this code multiple times, you can see that the output will sometimes either be 1, 2, 3 or 1, 3, 2. (This doesn't work on the playground, as the output is cached)

    评论

报告相同问题?

悬赏问题

  • ¥15 fesafe材料库问题
  • ¥35 beats蓝牙耳机怎么查看日志
  • ¥15 Fluent齿轮搅油
  • ¥15 八爪鱼爬数据为什么自己停了
  • ¥15 交替优化波束形成和ris反射角使保密速率最大化
  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统