2016-03-23 10 views
1

次のコードをこのlinkの最初の答えから変更しました。Pythonはスリープ中にスレッドを終了します

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

    def __init__(self, target, timeout): 
     super(StoppableThread, self).__init__() 
     self._target = target 
     self._timeout = timeout 
     self._stop = threading.Event() 
     self.awake = threading.Event() 

    def run(self): 
     while(not self._stop.isSet()): 
      self.awake.clear() 
      time.sleep(self._timeout) 
      self.awake.set() 
      self._target() 

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

    def stopped(self): 
     return self._stop.isSet() 

私は、このクラスのインスタンスを作成し、デーモンプロセスにそれを設定したら、私はスレッドが眠っているとき、後でそれを終了したいと思い、そうでなければ_target()機能を完了するのを待ってから、終了する。 stopメソッドを呼び出すことで後者のケースを処理できます。しかし、_awakeイベントオブジェクトがFalseに設定されているときに終了することはできません。誰かが助けてくれますか?

答えて

1

あなたのスレッドは明示的にsleepを必要としません。別のスレッドが停止を要求するのを待つだけです。

def run(self): 
    while(not self._stop.isSet()): 
     self.awake.clear() 
     self._stop.wait(self._timeout) # instead of sleeping 
     if self._stop.isSet(): 
      continue 
     self.awake.set() 
     self._target() 

この目的のために、あなたはまったくawakeイベントを必要としません。 (別のスレッドが "ステータス"を確認したい場合には、まだそれが必要かもしれませんが、あなたが持っている必要があるかどうかわかりません)。

awakeがなければ、あなたのコードは次のようになります。

class StoppableThread(threading.Thread): 

    def __init__(self, target, timeout): 
     super(StoppableThread, self).__init__() 
     self._target = target 
     self._timeout = timeout 
     self._stop = threading.Event() 

    def run(self): 
     while not self.stopped(): 
      self._stop.wait(self._timeout) # instead of sleeping 
      if self.stopped(): 
       continue 
      self._target() 

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

    def stopped(self): 
     return self._stop.isSet() 
+0

私はあなたのポイントを得ました。今、関数 'target'が無限に長く実行されているとすれば、それを正常に終了させるにはどうすればいいですか? MySQL DBトランザクションが含まれているので、正常に終了する必要があります。上記のような関数のタイムアウト条件はありません。タイムアウトの秒ごとに 'target'関数を定期的に実行することができます。 その関数のドライバ関数を作成し、新しいスレッドからドライバ関数を実行し、上記のスレッドの '_stop'イベントフラグを渡しますか?それとも良い方法がありますか? – zorro

+0

@zorroこれはまったく異なる質問ですので、新しい質問を投稿する必要があります(ルールごとに1つの質問があります)。 – shx2

+1

ありがとうございます。私はそれを行います。 – zorro

関連する問題