我需要使用一个只包含一个元素的队列,任何新元素都会丢弃现有元素。有内置的解决方案吗?
我编码的解决方案有效,但我努力不重新发明轮子:)
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()))
编辑:发表一些评论&答案 - 我知道变量只是为了那个:)但是在我的程序中,队列将用于进程之间的通信。
答案 0 :(得分:2)
当您指定使用队列在进程之间进行通信时,您应该使用multiprocesssing.Queue
。
为了确保队列中一次只有一个项目,您可以让生产者共享一个锁,并在锁定时,先从get_nowait
之前的队列中先put
。这类似于代码中的循环,但没有两个生成器的竞争条件,在放入新项目之前清空队列,因此最终得到队列中的两个项目。
答案 1 :(得分:0)
尽管OP是关于进程通信的,但是我遇到了这样一种情况:我需要一个带有单个元素的队列(这样,在添加新元素时会丢弃旧元素)在两个线程(生产者/消费者)之间。
以下代码说明了我使用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()
在上面的代码中,由于生产者比消费者快(睡眠少),因此某些元素将不被处理。
注释(来自文档):
双端队列支持线程安全的,内存高效的附加和弹出 双端队列的两侧具有大致相同的O(1)性能 在任何一个方向上。
一旦限长双端队列已满,则在添加新项目时, 从另一端丢弃相应数量的项目。
警告:代码永不停止:)