如何使用无限循环的目标函数创建可停止线程
How to make a stoppable thread with a target function that is an infinite loop
假设我想在线程中 运行 一个名为 run_forever()
的函数,但按 Ctrl[=27= 仍然有它 'stoppable' ]+C。我已经看到使用 threading.Thread
的 StoppableThread
子类来执行此操作的方法,但这些方法似乎涉及 'copying' 目标函数到该子类中。我想保留函数 'where it is'.
考虑以下示例:
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()
函数的情况下实现所需的行为?
我怀疑这是可能的。
顺便说一句,您是否尝试过第二种解决方案
ThreadWithExc
来自 the post 你之前链接过吗?
如果循环忙于纯 Python(例如没有 sleep
),它会起作用,否则我会切换到 multiprocessing
并终止子进程。这是希望优雅退出的代码(仅限*nix):
from multiprocessing import Process
from signal import signal, SIGTERM
import time
def on_sigterm(*va):
raise SystemExit
def fun():
signal(SIGTERM, on_sigterm)
try:
for i in xrange(5):
print 'tick', i
time.sleep(1)
finally:
print 'graceful cleanup'
if __name__=='__main__':
proc = Process(target=fun)
proc.start()
time.sleep(2.5)
proc.terminate()
proc.join()
假设我想在线程中 运行 一个名为 run_forever()
的函数,但按 Ctrl[=27= 仍然有它 'stoppable' ]+C。我已经看到使用 threading.Thread
的 StoppableThread
子类来执行此操作的方法,但这些方法似乎涉及 'copying' 目标函数到该子类中。我想保留函数 'where it is'.
考虑以下示例:
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()
函数的情况下实现所需的行为?
我怀疑这是可能的。
顺便说一句,您是否尝试过第二种解决方案
ThreadWithExc
来自 the post 你之前链接过吗?
如果循环忙于纯 Python(例如没有 sleep
),它会起作用,否则我会切换到 multiprocessing
并终止子进程。这是希望优雅退出的代码(仅限*nix):
from multiprocessing import Process
from signal import signal, SIGTERM
import time
def on_sigterm(*va):
raise SystemExit
def fun():
signal(SIGTERM, on_sigterm)
try:
for i in xrange(5):
print 'tick', i
time.sleep(1)
finally:
print 'graceful cleanup'
if __name__=='__main__':
proc = Process(target=fun)
proc.start()
time.sleep(2.5)
proc.terminate()
proc.join()