有没有“单槽”队列?
我需要一个队列,这个队列只能存放一个元素,任何新加的元素都会把原来的元素替换掉。有没有现成的解决方案?
我写的解决方案是可以用的,但我希望不要重复造轮子 :)
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
放入新的项目。这种做法和你代码里的循环有点像,但避免了两个生产者同时从队列里取东西,导致队列里出现两个项目的情况。