在Python中,如何让线程在多个队列上等待?
在下面的代码中,我有两个队列用于运行不同类型的线程。这些线程递归地添加到彼此的队列中(队列1获取一些信息,队列2处理这些信息并向队列1添加更多信息) 问题是,当第一个队列暂时用完了要做的事情时,它就会关闭,因此它永远看不到队列2(out_队列)在该点之后添加了什么 我添加了time.sleep()函数,这是一个非常黑客攻击的修复程序,到30秒,两个队列都已填满,不会耗尽 解决这个问题的标准Python方法是什么?我是否必须只有一个队列,并在其中标记项目,以确定它们应该由哪个线程处理在Python中,如何让线程在多个队列上等待?,python,multithreading,queue,Python,Multithreading,Queue,在下面的代码中,我有两个队列用于运行不同类型的线程。这些线程递归地添加到彼此的队列中(队列1获取一些信息,队列2处理这些信息并向队列1添加更多信息) 问题是,当第一个队列暂时用完了要做的事情时,它就会关闭,因此它永远看不到队列2(out_队列)在该点之后添加了什么 我添加了time.sleep()函数,这是一个非常黑客攻击的修复程序,到30秒,两个队列都已填满,不会耗尽 解决这个问题的标准Python方法是什么?我是否必须只有一个队列,并在其中标记项目,以确定它们应该由哪个线程处理 queue
queue = Queue.Queue()
out_queue = Queue.Queue()
class ThreadUrl(threading.Thread):
"""Threaded Url Grab"""
def __init__(self, queue, out_queue):
threading.Thread.__init__(self)
self.queue = queue
self.out_queue = out_queue
def run(self):
while True:
row = self.queue.get()
request = urllib2.Request(row[0], None, req_headers)
# ... some processing ...
self.out_queue.put([row, http_status, page])
self.queue.task_done()
class DatamineThread(threading.Thread):
def __init__(self, out_queue, mysql):
threading.Thread.__init__(self)
self.out_queue = out_queue
self.mysql = mysql
def run(self):
while True:
row = self.out_queue.get()
# ... some processing ...
queue.put(newrow)
self.out_queue.task_done()
queue = Queue.Queue()
out_queue = Queue.Queue()
for i in range(URL_THREAD_COUNT):
t = ThreadUrl(queue, out_queue)
t.setDaemon(True)
t.start()
#populate queue with data
for row in rows:
queue.put(row)
#MySQL Connector
mysql = MySQLConn(host='localhost', user='root', passwd = None, db='db')
#spawn DatamineThread, if you have multiple, make sure each one has it's own mysql connector
dt = DatamineThread(out_queue, mysql)
dt.setDaemon(True)
dt.start()
time.sleep(30)
#wait on the queue until everything has been processed
queue.join()
out_queue.join()
更改工作者,使其需要一个sentinel值才能退出,而不是在队列中没有更多工作时退出。在下面的代码中,
howdy
工作者从输入队列读取项目。如果该值是sentinel(None
,但它可以是任何值),则工人退出
因此,您不需要处理超时问题,正如您发现的那样,超时问题可能相当棘手。另一个结果是,如果有N个线程,则必须向输入队列附加N个sentinel以杀死工作线程。否则你会遇到一个永远等待的工人。一个僵尸工人,如果你愿意的话
来源
输出
我最近试着做一些类似的事情,并且想出了这个。我检查了每个队列的大小,然后一直排到它们都空了为止
inqueue = True
while inqueue:
time.sleep(5)
q1 = queue.qsize()
q2 = out_queue.qsize()
print("queue:%d,out_queue:%d"% (q1,q2))
inqueue = q1 or q2
queue.join()
out_queue.join()
可以显示ThreadUrl的源代码吗?它是否调用queue.get()?是的,它使用queue.get(),并且通常是第一个死的。您可以显示ThreadUrl的源代码,以便我们了解它死的原因吗?@rje感谢您抽出时间,因此我更新了代码以包含不同的类。我把它们缩短了一点,以“修剪脂肪”,我确信这些区域没有破坏脚本。我如何用两个线程来实现这一点,每个线程为彼此的队列提供数据?
howdy, whiskey
howdy, syrup
howdy, bitters
inqueue = True
while inqueue:
time.sleep(5)
q1 = queue.qsize()
q2 = out_queue.qsize()
print("queue:%d,out_queue:%d"% (q1,q2))
inqueue = q1 or q2
queue.join()
out_queue.join()