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 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥30 BC260Y用MQTT向阿里云发布主题消息一直错误
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了
  • ¥20 用雷电模拟器安装百达屋apk一直闪退