dongyu1918 2015-06-25 20:19
浏览 24
已采纳

开始-等待优先级队列中的下一个项目(如果为空)

I am trying to implement a priority queue to send json objects through a network socket based on priority. I am using the container/heap package to implement the queue. I came up with something like this:

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

Are there better ways to wait for a new item than just polling the priority queue?

  • 写回答

2条回答 默认 最新

  • dongpengqin3898 2015-06-25 23:11
    关注

    I'd probably use a couple a queuing goroutine. Starting with the data structures in the PriorityQueue example, I'd build a function like this:

    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
                }
            }
        }
    }
    

    Here's an example of using it:

    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()
    }
    

    Note that if you run this example, the order will be a little different every time. That's of course expected. It depends on exactly how fast the input and output channels run.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置