为什么这个http线程池会死(加入),但仍保持正常运行?

时间:2014-10-06 23:16:45

标签: python mysql multithreading

以下代码采用初始字符串(' a',' b'或' c'),两种线程类型来回传递,附加' W'和' H'重复一遍,标记工作线程或Http线程最后处理字符串。

代码是一个简单的测试,可以尝试并最终完成以下操作。 http线程池将拉取网页,工作线程将向db添加信息,然后为http线程提供更多的URL。他们只是来回走动。我希望线程池和队列都保持活动状态,除非BOTH同时为空。 (有些情况下,一个游泳池会暂时无法完成任务,而且我不想让它加入,因为它的伴随线程池很可能会很快为它添加更多的工作。)

在下面的代码中,http线程池几乎立即耗尽了所有事情,然后加入。但是你会发现线程仍在运行。

  • 为什么会这样做
  • 我如何才能这样做,所以在BOTH同时为空之前,两个队列都不能加入?

    from queue import Queue
    import threading
    import time
    
    class http(threading.Thread):
        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()
                print(row)
                self.out_queue.put(row+'H')
                self.queue.task_done()
    
    class worker(threading.Thread):
        def __init__(self, queue, out_queue):
            threading.Thread.__init__(self)
            self.queue = queue
            self.out_queue = out_queue
    
        def run(self):
            while True:
                time.sleep(1)
                row = self.out_queue.get()
                self.queue.put(row+'W')
                self.out_queue.task_done()
    
    
    URL_THREAD_COUNT = 3
    rows = [chr(x) for x in range(97, 100)]
    
    def main():    
        queue = Queue()
        out_queue = Queue()
    
    
        #spawn a pool of threads, and pass them queue instance
        for i in range(URL_THREAD_COUNT):
            t = http(queue, out_queue)
            t.daemon = True
            t.start()
    
        #populate queue with data
        for row in rows:
            queue.put(row)
    
        #spawn worker thread
        dt = worker(queue, out_queue)
        dt.daemon = True
        dt.start()
    
        #time.sleep(5)
    
        # wait for queues
        queue.join()
        print('EXIT http')
        out_queue.join()
        print('EXIT worker')
    
    start = time.time()
    main()
    print("Elapsed Time: %s" % (time.time() - start))
    

1 个答案:

答案 0 :(得分:1)

“加入”队列等待队列为空。如果worker在其他线程可以添加更多消息之前完成处理一些out_queue消息,则外部out_queue.join认为您已完成。您可能希望添加一条控制消息,告诉线程何时完成工作以便它们可以退出,并为它们调用thread.join()。这意味着保留在for循环中创建的线程列表,而不是仅仅放弃它们。