2017-12-20 9 views
0

停止可能なスレッドを作成するには、hereというポストされた解決策があります。しかし、私はいくつかの問題をこのソリューションを実装する方法を理解している。コードを使用してPython - どうすれば '停止可能な'スレッドを実装できますか?

...

import threading 

class StoppableThread(threading.Thread): 
    """Thread class with a stop() method. The thread itself has to check 
    regularly for the stopped() condition.""" 

    def __init__(self): 
     super(StoppableThread, self).__init__() 
     self._stop_event = threading.Event() 

    def stop(self): 
     self._stop_event.set() 

    def stopped(self): 
     return self._stop_event.is_set() 

は、どのように私は1秒ごとに端末にプリント「こんにちは」機能を実行するスレッドを作成することができます。 5秒後に.stop()を使用してループ関数/スレッドを停止します。

もう一度この解決策を実装する方法を理解するのに苦労しています。

import threading 
import time 

class StoppableThread(threading.Thread): 
    """Thread class with a stop() method. The thread itself has to check 
    regularly for the stopped() condition.""" 

    def __init__(self): 
     super(StoppableThread, self).__init__() 
     self._stop_event = threading.Event() 

    def stop(self): 
     self._stop_event.set() 

    def stopped(self): 
     return self._stop_event.is_set() 

def funct(): 
    while not testthread.stopped(): 
     time.sleep(1) 
     print("Hello") 

testthread = StoppableThread() 
testthread.start() 
time.sleep(5) 
testthread.stop() 

上記のコードは、testthread.stop()コマンドで停止できるスレッドtestthreadを作成します。私はこれが空のスレッドを作成していると理解しています... funct()を実行するスレッドを作成する方法はありますか、スレッドは.stop()を使用すると終了します。基本的には、スレッドとしてfunct()関数を実行するためにStoppableThreadクラスを実装する方法がわかりません。

通常のねじ切り機能の例...

import threading 
import time 

def example(): 
    x = 0 
    while x < 5: 
     time.sleep(1) 
     print("Hello") 
     x = x + 1 

t = threading.Thread(target=example) 
t.start() 
t.join() 
#example of a regular threaded function. 
+0

イベントに応じてスレッド内で何か処理を行う必要があります。たとえば、繰り返しごとに 'self.stopped'をチェックします。あなたがそうしない限り、スレッドは魔法のように動作を停止しません。 –

+0

testthread.stopped()ではないのですか? –

+0

スレッドを拡張したり、実行するタスクを渡すことはありません。あなたは 'funct'が動くと思いますか? –

答えて

0

は、あなたがあなたの元の例のコードを使用している方法で問題がいくつかあります。まず、基本コンストラクタにコンストラクタ引数を渡すことはありません。これは問題です。プレーンスレッドの例でわかるように、コンストラクタの引数がしばしば必要です。次のようにStoppableThread.__init__を書き換える必要があります。

def __init__(self, *args, **kwargs): 
    super().__init__(*args, **kwargs) 
    self._stop_event = threading.Event() 

をあなたは、Python 3を使用しているので、あなたがsuperに引数を提供する必要はありません。 funct自体を停止する外部変数、testthreadを使用しているため、今、あなたは

testthread = StoppableThread(target=funct) 

を行うことができますこれは、まだ最適なソリューションではありません。これはあなたのような小さな事例ではOKですが、そのようなグローバル変数を使用すると、通常は膨大な保守負担が発生し、実行したくありません。より良い解決策は、あなたが適切にselfにアクセスできるように、あなたの特定のタスクのための一般的なStoppableThreadクラスを拡張するために、次のようになります。

class MyTask(StoppableThread): 
    def run(self): 
     while not self.stopped(): 
      time.sleep(1) 
      print("Hello") 

testthread = MyTask() 
testthread.start() 
time.sleep(5) 
testthread.stop() 

あなたは絶対にStoppableThreadを拡張したくない場合は、あなたのタスクでcurrent_thread機能を使用することができますグローバル変数を読み込むのが優先です。

def funct(): 
    while not current_thread().stopped(): 
     time.sleep(1) 
     print("Hello") 

testthread = StoppableThread(target=funct) 
testthread.start() 
sleep(5) 
testthread.stop() 
+0

非常に役に立ちました!どうもありがとうございました! – FrontDoor

+0

これは実用的な解決策です。私はあなたの答えを見直すより多くの時間を費やして、私は学ぶことができます。ありがとう、トン! – FrontDoor

+0

@FrontDoor。あなたのために働いた喜び。実際にスレッドに関する質問が出ます。私はそれがあなたにかなり関連するかもしれないと思うので、私が投稿するとすぐに私はリンクします。 –

関連する問題