2

アクセスすると両方のスレッドが機能しますが、一緒に実行されるhalt_listenerと、リソースを独占しimport_1て実行できなくなります。最終的な目標は、halt_listener に kill メッセージをリッスンさせ、run 変数を false に設定することです。これは、halt_listener にパイプを送信していたときに機能しましたが、私はキューを好みます。

これが私のコードです:

import multiprocessing 
import time 
from threading import Thread

class test_imports:#Test classes remove 
      alive = {'import_1': True, 'import_2': True};

      def halt_listener(self, control_Queue, thread_Name, kill_command):
          while True:
              print ("Checking queue for kill")
              isAlive = control_queue.get()
              print ("isAlive", isAlive)
              if isAlive == kill_command:
                 print ("kill listener triggered")
                 self.alive[thread_Name] = False;
                 return

      def import_1(self, control_Queue, thread_Number):
          print ("Import_1 number %d started") % thread_Number
          halt = test_imports()
          t = Thread(target=halt.halt_listener, args=(control_Queue, 'import_1', 't1kill'))
          count = 0 
          t.run()
          global alive 
          run = test_imports.alive['import_1'];
          while run:
                print ("Thread type 1 number %d run count %d") % (thread_Number, count)
                count = count + 1
                print ("Test Import_1 ", run)
                run = self.alive['import_1'];
          print ("Killing thread type 1 number %d") % thread_Number 

何か不足していますか?

4

1 に答える 1

5

問題は、あなたが電話していることですt.run()runスレッドを開始するメソッドではありません。runスレッドで実行するための実際のコードです。直接呼び出すことでスレッドで実行し、終了するのを待ちます。

あなたが欲しいのはですt.start()

詳細については、ドキュメントを参照しthreading.Threadてください。


私たちがそれに取り組んでいる間、あなたのコードには他にもいくつかの問題があります。

まず、周りにロックがありませんself.alive。あるスレッドで値を変更し ( のような少数の自動自己同期型を除くQueue)、ロックなしで別のスレッドで値にアクセスすることはできません。多くの場合、問題は解決しますが、マルチスレッド プログラムで「しばしば」とは、大きなデモンストレーションまで失敗しないことを意味し、修正を開始する前に、再現方法を理解するのに数週間かかります... (この場合、条件はロックよりも意味があるかもしれませんが、いずれにせよ、何かを同期する必要があります。)

一方、ポーリングのためにできるだけ速くループするとself.alive['import_1']、正当な理由もなく 100% の CPU が消費されます。ほとんどの場合、何かを待機するためのより良い方法があります (たとえば、この場合、同期に条件を使用した場合は、ここで待機するためにも使用できます)。まれなケースではありませんが、少なくともsleepループを毎回実行する必要があります。

alive実際には、インスタンス属性ではなくクラス属性です。それは通常、あなたが望むものではありません。実際、 と の両方にアクセスしようとしますtest_imports.aliveself.alive、割り当てを行わない限り、どちらも class 属性になってしまい、混乱を招きます。その上、同じ名前のグローバルがあり、これは極度の混乱のレシピにすぎません。

また、これは Python 2 コードのように見えますがprint、場合によっては関数であるかのように使用していますprint ("isAlive", isAlive)。のようなものを出力する代わりに、isAlive commandのようなものを出力することになりますが('isAlive', 'command')、これはあまりきれいではありません。一方、式の余分な括弧は("Import_1 number %d started") % thread_Number、括弧が実際には何もしていないことを自分自身に納得させるために、誰かがそれを数回読む必要があることを意味します.

test_imports最後に、呼び出すために別のインスタンスを作成するのはなぜhalt_listenerですか? 明らかに、2 つのメソッドは の属性を介して通信しようとしてselfいますが、2 つの異なるオブジェクトで呼び出された場合は通信しません。だけではないのはなぜtarget=self.half_listenerですか?

于 2013-08-21T00:14:57.753 に答える