Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中,如何让线程在多个队列上等待?_Python_Multithreading_Queue - Fatal编程技术网

在Python中,如何让线程在多个队列上等待?

在Python中,如何让线程在多个队列上等待?,python,multithreading,queue,Python,Multithreading,Queue,在下面的代码中,我有两个队列用于运行不同类型的线程。这些线程递归地添加到彼此的队列中(队列1获取一些信息,队列2处理这些信息并向队列1添加更多信息) 问题是,当第一个队列暂时用完了要做的事情时,它就会关闭,因此它永远看不到队列2(out_队列)在该点之后添加了什么 我添加了time.sleep()函数,这是一个非常黑客攻击的修复程序,到30秒,两个队列都已填满,不会耗尽 解决这个问题的标准Python方法是什么?我是否必须只有一个队列,并在其中标记项目,以确定它们应该由哪个线程处理 queue

在下面的代码中,我有两个队列用于运行不同类型的线程。这些线程递归地添加到彼此的队列中(队列1获取一些信息,队列2处理这些信息并向队列1添加更多信息)

问题是,当第一个队列暂时用完了要做的事情时,它就会关闭,因此它永远看不到队列2(out_队列)在该点之后添加了什么

我添加了time.sleep()函数,这是一个非常黑客攻击的修复程序,到30秒,两个队列都已填满,不会耗尽

解决这个问题的标准Python方法是什么?我是否必须只有一个队列,并在其中标记项目,以确定它们应该由哪个线程处理

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()