我正在學習python多線程和隊列。下面創建了一堆,通過隊列將數據傳遞到另一個線程進行打印線程:python多線程隊列沒有運行或乾淨地退出
import time
import threading
import Queue
queue = Queue.Queue()
def add(data):
return ["%sX" % x for x in data]
class PrintThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
data = self.queue.get()
print data
self.queue.task_done()
class MyThread(threading.Thread):
def __init__(self, queue, data):
threading.Thread.__init__(self)
self.queue = queue
self.data = data
def run(self):
self.queue.put(add(self.data))
if __name__ == "__main__":
a = MyThread(queue, ["a","b","c"])
a.start()
b = MyThread(queue, ["d","e","f"])
b.start()
c = MyThread(queue, ["g","h","i"])
c.start()
printme = PrintThread(queue)
printme.start()
queue.join()
不過,我看只能從第一個線程打印出來的數據:再沒有什麼別的
['aX', 'bX', 'cX']
,但該程序不會退出。我必須殺死進程才能退出。
理想情況下,在每個MyThread
執行數據處理並將結果放入隊列後,該線程應該退出?同時PrintThread
應該採取任何隊列和打印它。
畢竟MyThread
線程已經完成並且PrintThread
線程已經完成處理隊列上的所有內容,程序應該乾淨地退出。
我做錯了什麼?
編輯:
如果每個MyThread
線程需要一段時間來處理,是有辦法保證PrintThread
線程將等待所有的MyThread
線程完成前,將退出本身?
這樣,打印線程肯定會處理隊列中的每個可能的數據,因爲所有其他線程已經退出。
例如,
class MyThread(threading.Thread):
def __init__(self, queue, data):
threading.Thread.__init__(self)
self.queue = queue
self.data = data
def run(self):
time.sleep(10)
self.queue.put(add(self.data))
上述修改將等待10秒鐘抹任何東西隊列之前。打印線程將運行,但我認爲它現在過早退出,因爲隊列中沒有數據,所以程序不打印任何內容。
如何解決'MyThread'線程需要5秒以上處理的問題?例如,如果我們在'MyThread'的'run()'之後放置'time.sleep(20)',最終的結果是空的;沒有打印出來。有沒有辦法保證'PrintThread'是最後退出的線程?這樣,無論其他線程處理數據的時間如何,所有數據都保證在隊列中,並且PrintThread有機會處理它們。 – warchest
您需要保持'PrintThread'運行,例如通過將其創建爲[守護線程](https://docs.python.org/3.5/library/threading.html#threading.Thread.daemon)。另一種方法是使用['threading.Event'](https://docs.python.org/3.5/library/threading.html#threading.Event)來指示線程停止主程序(如線程本身不知道是否期望更多的隊列中的項目)。 –
我設置了'printme。setDaemon(True)',但該程序正在打印一些奇怪的輸出。例如,我看到像'['gX','hX'或'['aX','bX','cX'] ['gX',''這是一個問題嗎? – warchest