run_forever()
という関数をスレッド内で実行したいとしますが、Cntrl + Cを押しても '停止可能'にします。私はthreading.Thread
のStoppableThread
サブクラスを使ってこれを行う方法を見てきましたが、これらはターゲット関数をそのサブクラスに 'コピー'する必要があります。代わりに機能を「どこに」置いておきたいのですか?無限ループであるターゲット関数で停止可能なスレッドを作成する方法
は、次の例を考えてみましょう:
import time
import threading
def run_forever(): # An externally defined function which runs indefinitely
while True:
print("Hello, world!")
time.sleep(1)
class StoppableThread(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""
def __init__(self, *args, **kwargs):
super(StoppableThread, self).__init__(*args, **kwargs)
self._stop = threading.Event()
def stop(self):
self._stop.set()
def stopped(self):
return self._stop.isSet()
def run(self):
while not self.stopped():
run_forever() # This doesn't work
# print("Hello, world!") # This does
self._stop.wait(1)
thread = StoppableThread()
thread.start()
time.sleep(5)
thread.stop()
ターゲット機能run_forever
が終了したことがないwhileループそのものです。しかし、望ましい動作を得るためには、私が理解しているように、wait()
コマンドはそのwhileループの中になければなりません。
run_forever()
機能を変更せずに目的の動作を達成する方法はありますか?
あなたは、単にあなたのプログラムが「CNTRL + Cを押して、 『停止可能』」になりたい場合は - ときに私私が意味するように解釈した「ハングしません'' Thread = StoppableThread(daemon = True) 'のように、Threadオブジェクトのデーモン属性をTrueに設定することができます。 – Billy
[Billy](http://stackoverflow.com/users/7007605/billy)、私はすでにデーモン化されたスレッドでこのような実装をしていますが、これらは突然停止します。私は優雅に停止するものが欲しいです。 –
'run_forever'関数を絶対に変更できない場合は、ここの答えの2番目の例と同様に、プラットフォームAPIに直接アクセスすることをお勧めします:http://stackoverflow.com/a/325528/7007605 – Billy