3

これらは、キューを使用した最初のスレッド化されたスクリプトの一部であるため、うまくいけば、これは私が間違っている小さなことです。基本的に、通り抜けた後、停止してそこに座りますが、終了しません。

import threading
import Queue
class Words(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.queue = Queue.Queue()     

    def word(self):
        read = open('words.txt')
        for word in read:
            word = word.replace("\n","")
            self.queue.put(word)       
        read.close() 
        for i in range(5):
            t = self.run()
            t.setDaemon(True)
            t.start()  
        self.queue.join()

    def run(self): 
        while True:
            word = self.queue.get()
            print word 
            self.queue.task_done()

    if __name__ == '__main__':
        Word =  Words()
        Word.word()
4

3 に答える 3

2

コードでいくつかの方法でスレッドを間違って使用しています。

まず、コードは、1 つのThreadサブクラス オブジェクトが作業を行うために必要なすべてのスレッドを生成できるという誤った前提に基づいて構築されているようです。それどころか、Threadドキュメントには、 「オブジェクトstartごとに最大で 1 回呼び出す必要がある」と記載されています。メソッドThreadの場合、これがリファレンスです。wordself

self.start()ただし、呼び出すと、単一のスレッドが生成されてキューが消費され、スレッド化からは何も得られないため、呼び出しは役に立ちません。複数のスレッドを開始するにはとにかくword新しいインスタンスを構築する必要があり、複数のインスタンスからキュー オブジェクトにアクセスする必要があるため、これらの両方をオブジェクトから分離すると便利です。たとえば、次のように始まるオブジェクト外の関数である可能性があります。WordsWordsWordswordWords

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()
于 2012-05-15T17:44:46.820 に答える
0

本当に単純な解決策が必要なときに、スレッドのさまざまな側面を混同しているように見えます。私の知る限りfor i in range(5):、スレッドを実行すると無限ループに陥るため、ループが最初の反復を超えることはありません。

これが私がそれをする方法です:

import threading
import Queue

class Worker(threading.Thread):
    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.queue = queue

    def run(self):
        while True:
            # try to dequeue a word from the queue
            try:
                word = self.queue.get_nowait()
            # if there's nothing in the queue, break because we're done
            except Queue.Empty:
                break

            # if the 'try' was successful at getting a word, print it
            print word


def fill_queue(queue):
    read = open('words.txt')
    for word in read:
        word = word.replace("\n", "")
        queue.put(word)
    read.close()


if __name__ == "__main__":
    # create empty queue
    queue = Queue.Queue()

    # fill the queue with work
    fill_queue(queue)

    # create 5 worker threads
    threads = []
    for i in range(5):
        threads.append(Worker(queue))

    # start threads
    for thread in threads:
        thread.start()

    # join threads once they finish
    for thread in threads:
        thread.join()
于 2012-05-15T17:39:33.677 に答える
0

Python のスレッド化されたコードの例を読みたい場合は、次のレシピでこのテーマに関する基本を学ぶことができます。それらのいくつかはデモンストレーションであり、他はプログラムです:

于 2012-05-15T18:55:15.053 に答える