gpt4 book ai didi

Go - 如果为空则等待优先级队列中的下一个项目

转载 作者:IT王子 更新时间:2023-10-29 00:45:20 27 4
gpt4 key购买 nike

我正在尝试实现一个优先级队列,以根据优先级通过网络套接字发送 json 对象。我正在使用 container/heap 包来实现队列。我想到了这样的事情:

for {
if pq.Len() > 0 {
item := heap.Pop(&pq).(*Item)
jsonEncoder.Encode(&item)
} else {
time.Sleep(10 * time.Millisecond)
}
}

有没有比轮询优先级队列更好的等待新项目的方法?

最佳答案

我可能会使用几个队列 goroutine。从 PriorityQueue example 中的数据结构开始,我会构建一个这样的函数:

http://play.golang.org/p/hcNFX8ehBW

func queue(in <-chan *Item, out chan<- *Item) {
// Make us a queue!
pq := make(PriorityQueue, 0)
heap.Init(&pq)

var currentItem *Item // Our item "in hand"
var currentIn = in // Current input channel (may be nil sometimes)
var currentOut chan<- *Item // Current output channel (starts nil until we have something)

defer close(out)

for {
select {
// Read from the input
case item, ok := <-currentIn:
if !ok {
// The input has been closed. Don't keep trying to read it
currentIn = nil
// If there's nothing pending to write, we're done
if currentItem == nil {
return
}
continue
}

// Were we holding something to write? Put it back.
if currentItem != nil {
heap.Push(&pq, currentItem)
}

// Put our new thing on the queue
heap.Push(&pq, item)

// Turn on the output queue if it's not turned on
currentOut = out

// Grab our best item. We know there's at least one. We just put it there.
currentItem = heap.Pop(&pq).(*Item)

// Write to the output
case currentOut <- currentItem:
// OK, we wrote. Is there anything else?
if len(pq) > 0 {
// Hold onto it for next time
currentItem = heap.Pop(&pq).(*Item)
} else {
// Oh well, nothing to write. Is the input stream done?
if currentIn == nil {
// Then we're done
return
}

// Otherwise, turn off the output stream for now.
currentItem = nil
currentOut = nil
}
}
}
}

这是一个使用它的例子:

func main() {
// Some items and their priorities.
items := map[string]int{
"banana": 3, "apple": 2, "pear": 4,
}

in := make(chan *Item, 10) // Big input buffer and unbuffered output should give best sort ordering.
out := make(chan *Item) // But the system will "work" for any particular values

// Start the queuing engine!
go queue(in, out)

// Stick some stuff on in another goroutine
go func() {
i := 0
for value, priority := range items {
in <- &Item{
value: value,
priority: priority,
index: i,
}
i++
}
close(in)
}()

// Read the results
for item := range out {
fmt.Printf("%.2d:%s ", item.priority, item.value)
}
fmt.Println()
}

请注意,如果您运行此示例,每次的顺序都会有所不同。这当然是预料之中的。这取决于输入和输出 channel 的运行速度。

关于Go - 如果为空则等待优先级队列中的下一个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31060023/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com