2013-03-31 30 views
8

申し訳ありません、古い質問です。私はそれを明確にした。貧弱なスレッドクラスで停止スレッドを開始するにはどうすればよいですか?スレッドの開始と停止方法は?

EDIT:ループ中です。コードの先頭で再起動します。 start-stop-restart-stop-restartを実行するにはどうすればよいですか?

私のクラス:メインコードで

import threading 

class Concur(threading.Thread): 
    def __init__(self): 
     self.stopped = False 
     threading.Thread.__init__(self) 

    def run(self): 
     i = 0 
     while not self.stopped: 
      time.sleep(1) 
      i = i + 1 

、私が欲しい:

inst = Concur() 

while conditon: 
    inst.start() 

    #after some operation 
    inst.stop() 
    #some other operation 

答えて

6

これはDavid Heffernanの考え方です。以下の例は1秒間実行され、その後1秒間停止してから1秒間実行されます。

import time 
import threading 
import datetime as DT 
import logging 
logger = logging.getLogger(__name__) 

def worker(cond): 
    i = 0 
    while True: 
     with cond: 
      cond.wait() 
      logger.info(i) 
      time.sleep(0.01) 
      i += 1 

logging.basicConfig(level=logging.DEBUG, 
        format='[%(asctime)s %(threadName)s] %(message)s', 
        datefmt='%H:%M:%S') 

cond = threading.Condition() 
t = threading.Thread(target=worker, args=(cond,)) 
t.daemon = True 
t.start() 

start = DT.datetime.now() 
while True: 
    now = DT.datetime.now() 
    if (now-start).total_seconds() > 60: break 
    if now.second % 2: 
     with cond: 
      cond.notify() 
3

stop()の実装は次のようになります。あなたが再起動する場合は

def stop(self): 
    self.stopped = True 

、新しいインスタンスを作成して開始することができます。 Threadため

while conditon: 
    inst = Concur() 
    inst.start() 

    #after some operation 
    inst.stop() 
    #some other operation 

documentationはそれを明確にstart()方法が唯一のクラスのインスタンスごとに一度呼び出すことができます。

スレッドを一時停止して再開するには、condition variableを使用する必要があります。

+0

それがループ内にある、私は初めに再びそれを再起動しますコードのstart-stop-restart-stop-restartを実行するにはどうすればよいですか? – user2229183

+0

彼の "メインコード"はループ内のスレッドを再起動しようとします。 – user4815162342

+0

申し訳ありませんが、私はthsiサイトを初めて利用しています。申し訳ありません – user2229183

11

そのrun()メソッドが終了した後に再度そのstart()を呼び出すことはできませんので、あなたが実際に、停止してスレッドを再起動することはできません。ただし、実行状態を確認または変更するときに同時実行の問題を避けるために、threading.Condition変数を使用することで、メソッドを効果的に一時停止してから再開させることができます。

Conditionオブジェクトには、それが解放されるまで待機するオブジェクトとメソッドがあり、発生したときに待機中のスレッドに通知します。ここでは、これが行われていることを示すあなたの質問のコードから派生した例を示します。この場合、私はより良い、追加のグローバル変数の導入を回避することにより、実装をカプセル化するCondition変数Threadサブクラスのインスタンスの一部を作った:

import threading 
import time 

class Concur(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self) 
     self.iterations = 0 
     self.daemon = True # OK for main to exit even if instance is still running 
     self.paused = True # start out paused 
     self.state = threading.Condition() 

    def run(self): 
     self.resume() # unpause self 
     while True: 
      with self.state: 
       if self.paused: 
        self.state.wait() # block until notified 
      # do stuff 
      time.sleep(.1) 
      self.iterations += 1 

    def resume(self): 
     with self.state: 
      self.paused = False 
      self.state.notify() # unblock self if waiting 

    def pause(self): 
     with self.state: 
      self.paused = True # make self block and wait 

class KeepRunning(object): 
    def __init__(self, seconds=10): 
     self.run_time = seconds 
     self.start_time = time.time() 

    @property 
    def condition(self): 
     return time.time()-self.start_time < self.run_time 

running = KeepRunning() 
concur = Concur() 
concur.start() # calls run() method 

while running.condition: 
    concur.resume() 

    #after some operation 
    concur.pause() 
    #some other operation 

print('concur.iterations == {}'.format(concur.iterations)) # show thread executed 
関連する問題