Python

python 优雅的中止任务

2022-09-20  本文已影响0人  alue

例如,我们有一个耗时任务 task

def task():
    while True:
        print(f'task is running!')
        time.sleep(1)

在主线程,可以根据用户输入,随时中止该任务。
一种容易出错的写法是这样:

import threading
import sys

t1 = threading.Thread(target=task)
t1.start()
while True:
    code = input()
    if code == 'stop':
        sys.exit()
    print(code)

当主程序执行到 sys.exit() 时,屏幕上仍然不断打印 task is running!, 只是shell不再接收用户的输入了。这说明,task 线程仍然在运行,阻碍了主程序的退出。

原因是,Python中,非daemon线程并不会随着主线程的退出而退出,daemon 线程则会随着主线程的退出而被杀死。

所以一个简单的改变,让task对应的线程变成deamon线程即可。增加一行代码

t1.daemon = True # 设置线程t1为deamon 线程,则t1会随着 sys.exit() 而死去

不过,这里是强制杀死t1线程,其调用的资源可能不会被正确的释放,因此会导致诡异bug。因此,不推荐这样使用。

更推荐的是使用进程的方式,来管理任务。

import multiprocessing

if __name__ == "__main__":
    process = multiprocessing.Process(target=task)
    process.daemon = True # 这样主进程退出后,task进程也会退出,跟线程类似  a daemonic process is not allowed to create child processes. 
    process.start()

    while True:
        code = input()
        if code == 'stop':
            process.terminate()
            sys.exit()

这是因为,线程之间会共享全局变量,但进程之间是完全隔离的执行环境,所以关闭进程要比关闭线程安全很多。

上一篇 下一篇

猜你喜欢

热点阅读