1

次のコードがブロックされる理由がわかりません。一定時間ループしてから、スレッドにメッセージを送信して停止しようとしています。私のプロセスクラスは次のとおりです。

class Worker(multiprocessing.Process):
    def __init__(self, queue):
        multiprocessing.Process.__init__(self)
        self.queue = queue
        self.running = True

    def run(self):
        print 'entered run'
        while self.running:
            print 'thread time:', time.time()
            time.sleep(.6)
        print 'thread end'
        return 0

かなり簡単です。私のメインは次のようになります。

if __name__ == '__main__':
    queue = Queue()
    p = Worker(queue)
    p.daemon = True
    p.start()
    time.sleep(3)
    p.running = False
    print 'Main end'

したがって、このプログラムが行うことを期待しているのは、メインのループに沿って独自のループを実行するプロセスを開始することです。それが起こっている間、Main()3 秒間スリープし、ワーカー プロセス内のループ条件を False に設定して、ループから抜け出します。次に、両方とも「完了」メッセージを出力し、プログラムを終了します。ただし、問題はmain、プロセスがメッセージを表示する前にスレッドが終了することです。

たとえば、出力は次のようになります。

>> entered run
>> thread time: 1358444245.31
>> thread time: 1358444245.91
>> thread time: 1358444246.51
>> thread time: 1358444247.11
>> thread time: 1358444247.71
>> Main end

それで、少し読んでjoin()、スレッドが実行を終了するまでブロックするために使用されていることがわかります。join()これに続いて、スレッドのループ条件を中断した直後に呼び出しを追加します。私の考えでは、プロセスが終了するまで、これは main をブロックします。

if __name__ == '__main__':
    queue = Queue()
    p = Worker(queue)
    p.daemon = True
    p.start()
    time.sleep(3)
    p.running = False
    p.join()          ## <------ New Line 
    print 'Main end'

ただし、これは予期しない動作をします。その行を追加すると、スレッドは実行を停止しないため、メイン ブロックは無期限に停止します。以下の出力は永遠にスピンアウトします。

>> entered run
>> thread time: 1358444362.44
>> thread time: 1358444363.04
>> thread time: 1358444363.64
>> thread time: 1358444364.24
>> thread time: 1358444364.84
>> thread time: 1358444365.44
>> thread time: 1358444366.04
>> thread time: 1358444366.64
>> thread time: 1358444367.24
>> thread time: 1358444367.84
>> thread time: 1358444368.44
>> thread time: 1358444369.04
>> thread time: 1358444369.64
>> thread time: 1358444370.24

何が起きてる?スレッドを追加join()しても、ループから抜け出せないのはなぜですか?

4

1 に答える 1

2

まず、multiprocessing.Processは を作成せずThread、提供された関数を実行する別のプロセスを作成します。

multiprocessing.Queue2 つのプロセス間でメッセージを渡すために使用する必要があります。

見てみましょう: http://docs.python.org/2/library/multiprocessing.html#exching-objects-between-processes

Max Yakimets が言及したように、最初のプロセス内で値を変更していますが、2 番目のプロセスにメッセージを渡すことはありません。

値を変更する代わりにp.running、キューにアイテムを追加する必要があります。プロセス内で、キュー内で待機しているメッセージがあるかどうかを確認し、それらに対応する必要があります (シャットダウンする、何か他のことを行うなど)。

于 2013-01-17T18:30:38.863 に答える