start()
メソッドが終了した後にそのメソッドを再度呼び出すことはできないため、スレッドを実際に停止してから再起動することはできませんrun()
。ただし、変数を使用して実行を停止し、後で実行を再開してthreading.Condition
、実行状態を確認または変更する際の同時実行の問題を回避することができます。
threading.Condition
オブジェクトには、解放されるのを待機するオブジェクトとメソッドが関連付けられており、threading.Lock
解放されると待機中のスレッドに通知されます。これが行われていることを示す質問のコードから派生した例を次に示します。サンプル コードでは、Condition
変数をサブクラス インスタンスの一部にThread
して、実装をより適切にカプセル化し、追加のグローバル変数を導入する必要がないようにしました。
from __future__ import print_function
import threading
import time
class Concur(threading.Thread):
def __init__(self):
super(Concur, self).__init__()
self.iterations = 0
self.daemon = True # Allow main to exit even if still running.
self.paused = True # Start out paused.
self.state = threading.Condition()
def run(self):
self.resume()
while True:
with self.state:
if self.paused:
self.state.wait() # Block execution until notified.
# Do stuff...
time.sleep(.1)
self.iterations += 1
def pause(self):
with self.state:
self.paused = True # Block self.
def resume(self):
with self.state:
self.paused = False
self.state.notify() # Unblock self if waiting.
class Stopwatch(object):
""" Simple class to measure elapsed times. """
def start(self):
""" Establish reference point for elapsed time measurements. """
self.start_time = time.time()
return self
@property
def elapsed_time(self):
""" Seconds since started. """
try:
return time.time() - self.start_time
except AttributeError: # Wasn't explicitly started.
self.start_time = time.time()
return 0
MAX_RUN_TIME = 5 # Seconds.
concur = Concur()
stopwatch = Stopwatch()
print('Running for {} seconds...'.format(MAX_RUN_TIME))
concur.start()
while stopwatch.elapsed_time < MAX_RUN_TIME:
concur.resume()
# Can also do other concurrent operations here...
concur.pause()
# Do some other stuff...
# Show Concur thread executed.
print('concur.iterations: {}'.format(concur.iterations))