是否有可能终止一个正在运行的线程而不设置/检查任何标志/信号/等等?
当前回答
有一个图书馆就是为了这个目的而建的,别说了。尽管这里列出的一些注意事项仍然适用,但至少这个库提供了一种常规的、可重复的技术来实现既定的目标。
其他回答
正如其他人所提到的,规范是设置一个停止标志。对于一些轻量级的东西(没有Thread的子类化,没有全局变量),lambda回调是一个选项。(注意if stop()中的括号。)
import threading
import time
def do_work(id, stop):
print("I am thread", id)
while True:
print("I am thread {} doing something".format(id))
if stop():
print(" Exiting loop.")
break
print("Thread {}, signing off".format(id))
def main():
stop_threads = False
workers = []
for id in range(0,3):
tmp = threading.Thread(target=do_work, args=(id, lambda: stop_threads))
workers.append(tmp)
tmp.start()
time.sleep(3)
print('main: done sleeping; time to stop the threads.')
stop_threads = True
for worker in workers:
worker.join()
print('Finis.')
if __name__ == '__main__':
main()
将print()替换为始终刷新的pr()函数(sys.stdout.flush())可以提高shell输出的精度。
(仅在Windows/Eclipse/Python3.3上测试)
使用setDaemon(True)启动子线程。
def bootstrap(_filename):
mb = ModelBootstrap(filename=_filename) # Has many Daemon threads. All get stopped automatically when main thread is stopped.
t = threading.Thread(target=bootstrap,args=('models.conf',))
t.setDaemon(False)
while True:
t.start()
time.sleep(10) # I am just allowing the sub-thread to run for 10 sec. You can listen on an event to stop execution.
print('Thread stopped')
break
如果您显式地调用time.sleep()作为线程的一部分(比如轮询一些外部服务),对Phillipe方法的改进是在sleep()的任何地方使用事件的wait()方法中的超时。
例如:
import threading
class KillableThread(threading.Thread):
def __init__(self, sleep_interval=1):
super().__init__()
self._kill = threading.Event()
self._interval = sleep_interval
def run(self):
while True:
print("Do Something")
# If no kill signal is set, sleep for the interval,
# If kill signal comes in while sleeping, immediately
# wake up and handle
is_killed = self._kill.wait(self._interval)
if is_killed:
break
print("Killing Thread")
def kill(self):
self._kill.set()
然后运行它
t = KillableThread(sleep_interval=5)
t.start()
# Every 5 seconds it prints:
#: Do Something
t.kill()
#: Killing Thread
使用wait()而不是sleep()ing和定期检查事件的优点是,您可以在更长的睡眠间隔中编程,线程几乎立即停止(否则您将处于sleep()ing),并且在我看来,处理退出的代码明显更简单。
你不应该在没有与线程合作的情况下强行终止线程。
杀死一个线程消除了try/finally阻塞设置的任何保证,所以你可能会让锁锁定,文件打开等等。
唯一可以认为强制终止线程是一个好主意的情况是快速终止程序,但绝不是单个线程。
多处理。进程可以p.terminate()
如果我想杀死一个线程,但不想使用标志/锁/信号/信号量/事件/任何东西,我就把线程提升到完整的进程。对于只使用几个线程的代码,开销并没有那么糟糕。
例如,这可以方便地终止执行阻塞I/O的助手“线程”
转换很简单:在相关代码中替换所有线程。多线程线程。进程和所有队列。多处理队列。排队并将p.t terminate()所需的调用添加到想要杀死子进程p的父进程中
关于多处理,请参阅Python文档。
例子:
import multiprocessing
proc = multiprocessing.Process(target=your_proc_function, args=())
proc.start()
# Terminate the process
proc.terminate() # sends a SIGTERM
推荐文章
- 如何禁用标准错误流的日志记录?
- 用Matplotlib在Python中绘制时间
- 类中的Python装饰器
- 在Python中锁定文件
- 得到熊猫栏目的总数
- 从pandas DataFrame中删除名称包含特定字符串的列
- Mock vs MagicMock
- 如何阅读一个。xlsx文件使用熊猫库在iPython?
- 如何访问熊猫组由数据帧按键
- Pandas和NumPy+SciPy在Python中的区别是什么?
- 将列表转换为集合会改变元素的顺序
- 如何在matplotlib更新一个情节
- TypeError: ` NoneType `对象在Python中不可迭代
- 如何在Vim注释掉一个Python代码块
- python标准库中的装饰符(特别是@deprecated)