コードでいくつかの方法でスレッドを間違って使用しています。
まず、コードは、1 つのThread
サブクラス オブジェクトが作業を行うために必要なすべてのスレッドを生成できるという誤った前提に基づいて構築されているようです。それどころか、Thread
ドキュメントには、 「オブジェクトstart
ごとに最大で 1 回呼び出す必要がある」と記載されています。メソッド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()
ここで例外を使用すると便利です。そうしないと、キューが空になり、スレッドがそこから取得しようとして、アイテムが追加されるのを永遠に待機することになる可能性があります。
3 番目に、 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()