为了账号安全,请及时绑定邮箱和手机立即绑定

golang fifo 缓冲通道

golang fifo 缓冲通道

Go
catspeake 2022-01-10 10:43:56
据我了解:当通道已满时,GO 中的缓冲通道不是 FIFO。我在我的应用程序中需要这种行为(FIFO 行为)。我怎样才能实现这种行为?有什么开源的吗?提前致谢编辑:有些人不喜欢这个问题,所以让我更清楚一点:我的意思是,当缓冲通道已满并且多个发送者在尝试将项目添加到通道时被阻止时,它们将被释放的顺序不是 FIFO。您还可以阅读此讨论:https : //github.com/golang/go/issues/11506所以,是的,我一直在寻找实现该行为的第三方库。抱歉不清楚。
查看完整描述

2 回答

?
倚天杖

TA贡献1828条经验 获得超3个赞

Go 中的缓冲通道始终是 FIFO。规范清楚地说:


通道充当先进先出队列。


如果来自通道的值不是 FIFO,那么这是通道实现中的错误。


以下代码应始终按正确顺序打印 1、2、3、4:


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)

    }

}


请注意,当有多个并发发送者时,不保证先发送哪个值。如果有多个等待发送者并且有人从通道缓冲区中删除了一个元素(或者在无缓冲通道的情况下,尝试从通道接收),运行时将随机选择一个发送 goroutine。


例子:


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)

    }

}


如果您多次运行此代码,您会看到输出有时为 1、2、3 或 1、3、2。(这在操场上不起作用,因为输出已缓存)


查看完整回答
反对 回复 2022-01-10
?
慕的地6264312

TA贡献1817条经验 获得超6个赞

您可以使用链接列表。


container/list 包 ( https://golang.org/pkg/container/ ) 实现了一个可以用作队列的双向链表。也许,它还实现了 Heap,它允许您创建具有优先级的队列。总之,最简单的方法是链表 IHMO:


queue := list.New()


queue.PushBack("Hello ") // Enqueue

queue.PushBack("world!")


for queue.Len() > 0 {

    e := queue.Front() // First element

    fmt.Print(e.Value)


    queue.Remove(e) // Dequeue

}


查看完整回答
反对 回复 2022-01-10
  • 2 回答
  • 0 关注
  • 201 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信