您正在使用的線程錯誤地在一對夫婦在你的代碼的方式:
首先,代碼似乎是在不正確的假設建造的一個Thread
子類對象可以派生出完成工作所需的所有線程。相反,Thread
documentation表示start
「必須每個Thread
對象最多調用一次」。在word
方法的情況下,這是self
參考。
但是,調用self.start()
是沒有用的,因爲這會產生一個單獨的線程來佔用隊列,並且您不會從線程中獲得任何東西。由於word
無論如何都必須構建新實例Words
以啓動多個線程,並且隊列對象需要由多個Words
實例訪問,因此將這兩個實例與Words
對象分開將是有用的。例如,word
可能是開始象Words
對象的外部的功能:
def word():
queue = Queue.Queue()
read = open('words.txt')
for word in read:
word = word.replace("\n","")
self.put(word)
read.close()
#...
這也意味着Words
將不得不採取隊列對象作爲參數,使得多個實例將共享相同的隊列:
class Words(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
其次,你的線程函數(run
)是一個無限循環,所以線程不會終止。既然你只運行隊列消費者線程已將所有項目到隊列後,你不應該終止線程的問題,一旦隊列是空的,就像這樣:
def run(self):
while True:
try:
word = self.queue.get(False)
except Queue.Empty:
break
print word
self.queue.task_done()
它是使用異常有用在這裏,因爲否則隊列可能會清空,然後線程可能會嘗試從中取出,並且最終會永久等待添加項目。第三,在您的for循環中,您調用self.run()
,它將控制傳遞給run
方法,該方法在方法更改爲終止後處理整個隊列並返回None
。以下幾行將引發異常,因爲t
將被分配值None
。既然你想產卵其他線程做這項工作,你應該做t = Word(queue)
獲得一個新的字線程,然後t.start()
開始。所以,當放在一起的代碼應該是
class Words(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while True:
try:
word = self.queue.get(False)
except Queue.Empty:
break
print word
self.queue.task_done()
def word():
queue = Queue.Queue()
read = open('words.txt')
for word in read:
word = word.replace("\n","")
self.put(word)
read.close()
for i in range(5):
t = Word()
t.setDaemon(True)
t.start()
queue.join()
if __name__=='__main__':
word()
所以,在這段代碼中,你要旋轉起來5個線程來處理隊列中的所有項目? –