根据我的理解:当通道满时,GO中的缓冲通道不是FIFO
我在我的应用程序中需要这种行为(FIFO行为)
我怎样才能实现这种行为?那是否有任何开源?
提前致谢
编辑:
有些人不喜欢这个问题,所以让我更清楚一点:
我的意思是当缓冲的频道已满且多个发件人被阻止时
在尝试向频道添加项目时,他们将被释放的顺序
不是FIFO。您还可以阅读此讨论:https://github.com/golang/go/issues/11506
所以是的,我正在寻找实现这种行为的第三方图书馆 很抱歉不清楚。
答案 0 :(得分:8)
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)
}
}
请注意,当有多个并发发件人时,没有担保人会先发送哪个值。如果有多个等待发送者,并且有人从通道缓冲区中删除了一个元素(或者在无缓冲通道的情况下,尝试从通道接收),运行时将随机选择一个发送goroutines。
示例:
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。(这在操场上不起作用,因为输出被缓存)< / p>
答案 1 :(得分:1)
您可以使用链接列表。
容器/列表包(https://golang.org/pkg/container/)实现了一个双向链接列表,该列表可用作队列。也许,它还实现了堆,该堆允许您创建具有优先级的队列。无论如何,最简单的方法是链接列表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
}