有没有“单槽”队列?

7 投票
2 回答
3653 浏览
提问于 2025-04-18 11:34

我需要一个队列,这个队列只能存放一个元素,任何新加的元素都会把原来的元素替换掉。有没有现成的解决方案?

我写的解决方案是可以用的,但我希望不要重复造轮子 :)

import Queue

def myput(q, what):
    # empty the queue
    while not q.empty():
        q.get()
    q.put(what)

q = Queue.Queue()
print("queue size: {}".format(q.qsize()))
myput(q, "hello")
myput(q, "hello")
myput(q, "hello")
print("queue size: {}".format(q.qsize()))

补充:根据一些评论和回答——我知道一个变量就可以做到这一点 :) 不过在我的程序中,队列是用来在不同的进程之间进行通信的。

2 个回答

1

虽然原问题是关于进程间通信的,但我遇到了一个情况,需要在两个线程(生产者/消费者)之间设置一个只允许一个元素的队列(也就是说,当添加新元素时,旧元素会被丢弃)。

下面的代码展示了我用 collections.deque 实现的解决方案,这个在评论中提到过:

import collections
import _thread
import time

def main():

    def producer(q):
       i = 0
       while True:
           q.append(i)
           i+=1
           time.sleep(0.75)


    def consumer(q):
        while True:
            try:
                v = q.popleft()
                print(v)
            except IndexError:
                print("nothing to pop...queue is empty")
                sleep(1)

    deq = collections.deque(maxlen=1)
    print("starting")
    _thread.start_new_thread(producer, (deq,))
    _thread.start_new_thread(consumer, (deq,))


if __name__ == "__main__":
    main()

在上面的代码中,由于生产者的速度比消费者快(休眠时间少),所以有些元素将不会被处理。

注意(来自文档):

双端队列(deque)支持线程安全的、内存高效的从队列两端添加和删除元素,性能大约都是 O(1),无论是从哪一端。

一旦有界长度的双端队列满了,当添加新项目时,会从另一端丢弃相应数量的项目。

警告:这段代码永远不会停止 :)

3

你提到你在使用队列来让不同的进程之间进行沟通,那么你应该使用multiprocessing.Queue

为了确保队列里一次只有一个项目,你可以让生产者们共享一个锁。在锁定的状态下,先用get_nowait从队列中取出一个项目,然后再用put放入新的项目。这种做法和你代码里的循环有点像,但避免了两个生产者同时从队列里取东西,导致队列里出现两个项目的情况。

撰写回答