[英]How to put an item back to a queue.Queue
您如何将项目返回到 queue.Queue? 如果任务失败,这将在线程或多处理中很有用,这样任务就不会丢失。
queue.Queue.get()的文档说该函数可以“从队列中删除并返回一个项目”,但我相信这里使用的“返回”一词是指将项目返回给调用线程的函数,不将其放回项目队列。 下面的示例代码证明了这一点,它只是在主线程的第二个queue.Queue.get()
调用上无限queue.Queue.get()
,而不是在线程中进行print()
调用。
import time
import threading
import queue
def threaded_func():
thread_task = myqueue.get()
print('thread_task: ' + thread_task)
myqueue = queue.Queue()
myqueue.put('some kind of task')
main_task = myqueue.get()
print('main_task: ' + main_task)
t = threading.Thread(target=threaded_func)
t.daemon = True
t.start()
time.sleep(5)
myqueue.get() # This blocks indefinitely
我不得不相信有一种简单的方法可以将任务放回去,那么它是什么? 调用task_done()
然后用任务put()
在两个操作中将其放回队列不是原子的,因此可能导致丢失项目。
一种可能但笨拙的解决方案是尝试再次执行任务,但是您必须添加一些额外的行来处理这种复杂性,而且我什至不确定所有失败的任务是否一定能在其中恢复道路。
并非所有失败的任务都可以恢复。 您不应该重试它们,除非有理由认为它们会在以后通过。 例如,如果您的工作项是一个 URL 并且连接失败计数,您可以实现某种最大重试次数。
你最大的问题是你还没有实现一个可行的工人模型。 您需要 2 个队列才能与工作人员进行双向对话。 一个用于发布工作项,一个用于接收状态。 一旦你有了它,接收者总是可以决定将该消息塞回到工作队列中。 这是一个懒惰的工人的例子,它只是通过了它所说的。
import threading
import queue
def worker(in_q, out_q):
while True:
try:
task, data = in_q.get()
print('worker', task, data)
if task == "done":
return
elif task == "pass this":
out_q.put(("pass", data))
else:
out_q.put(("fail", data))
except Exception as e:
print('worker exception', e)
out_q.put("exception", data)
in_que = queue.Queue()
out_que = queue.Queue()
work_thread = threading.Thread(target=worker, args=(in_que, out_que))
work_thread.start()
# lets make every other task a fail
in_que.put(('pass this', 0))
in_que.put(('fail this', 1))
in_que.put(('pass this', 2))
in_que.put(('fail this', 3))
in_que.put(('pass this', 4))
in_que.put(('fail this', 5))
pending_tasks = 6
while pending_tasks:
status, data = out_que.get()
if status == "pass":
pending_tasks -= 1
else:
# make failing tast pass
in_que.put(('pass this', data))
in_que.put(("done", None))
work_thread.join()
print('done')
您可以使用PriorityQueue ,其中条目按优先级顺序返回。
from tornado.queues import PriorityQueue
q = PriorityQueue()
q.put((2, 'item 1'))
q.put((2, 'item 2'))
q.get() # item 1
q.put((1, 'item 1')) # put item 1 back on the queue
q.get() # item 1
q.get() # item 2
请注意, get()
的返回也是优先级编号和项目的元组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.