如何在不同Python文件中终止线程?

嘿嘿,你的总结很完整,但是如果我直接用的话可能会有点混乱。
我们分不同场景来谈谈这个问题。

例如,我上次在上海做一个项目,需要在后台运行一个数据处理进程,但有时不得不远程强制停止。
当时我用的就是你说的第一种方法。
将流程创建代码直接放在 script1 .py 中,不使用 if __name__ == "__main__": package。
然后直接将script1 导入到script2 .py中,得到一个demo对象,点击demo.terminate()终止它。
简单、原始且非常易于使用。
然而,我的陷阱之一是有一天我忘记更改它并将 script1 导入到测试脚本中。
结果我本地启动服务的时候,进程启动了两次。
我当时真的哭笑不得,所以我很快添加了一个全局变量来确定它是否正在运行。
这种方法适合那些只运行固定进程而不关心别人如何使用的人。

后来换了项目,需求变得更加复杂。
我必须根据命令创建具有不同配置的进程,并且其中多个进程可能同时运行。
这次我使用方法2 将进程创建代码包装在run_process()函数中。
只需在运行文件中 demo = run_process() 并根据需要进行配置即可。
优点是灵活。
如果你想运行任意多个,你可以只传递几个参数并创建任意多个。
当一个函数没有被使用时,就根本不调用它。
这次一切都安全多了,不再出现反复出现的启动问题。
但缺点是它需要一些额外的函数调用层,这对于新手来说可能有点混乱。

至于线程,我已经进入了一个更大的洞。
该系统去年在深圳建成,使用线程处理用户请求,但随着用户数量的增加而崩溃。
后来发现,这是一条死胡同。
两个线程正在等待对方阻塞并被卡住。
现在想一下:Python线程不能直接terminate(),它们只能依赖共享变量或事件。
因此,在这种情况下,您应该在开始文件中有一个全局 stop_event = threading.Event(),在线程循环中检查该事件,然后在结束文件中检查 stop_event.set() 和 thread.join() 。
但问题是你需要确保所有线程都能优雅地响应这个事件并退出,否则它们仍然会卡住。
我花了两天时间才确定哪个线程没有响应该事件,并且很难更改它。
因此,在一般线程中,除非您了解死锁和资源争用,否则不要随机出现在不同的文件中。
一起出去更安全。

您需要记住您提到的注意事项,例如使用Queue或Pipe进行进程间通信以及完成后使用join()。
尤其是资源清理过程。
上次我忘了添加 demo.join()。
结果,终端留下了一堆僵尸进程,让操作员和维护员的工作不堪重负。

无论如何,都由你决定。
如果容易,就使用第一种方法,如果困难,就使用第二种方法。
要特别注意退出协作的线程,而不要只考虑强制终止。
我还在想这个问题。
有时候我觉得Python的多进程多线程机制真的很难设计。

python的线程join怎么用

说白了,Python的线程join()就是用来阻塞主线程,等待子线程完成工作的。
超时和守护线程活动使情况变得复杂。

首先我们来说说最重要的join(),它会直接hold住主线程,直到子线程运行完毕。
去年我们跑那个项目的时候,五个爬虫子线程没有参与,主线程挂了,日志也不完整。
还有一点,等待时间是一个形而上的东西。
守护线程模式下,超时后子线程将被强制关闭。
去年,我们忘记添加超时。
结果是爬虫卡在数据库连接中,整批任务爆炸。
还有另一个重要的细节。
即使非守护线程超时,子线程也可以继续秘密运行,直到其运行完毕。
很多人不注意这一点。

一开始我以为加入就意味着等待子线程,但后来我发现守护线程模式根本就是一个陷阱。
它必须等待超时或主线程退出,这可能会导致程序先运行。
等等,还有别的事。
在非守护线程模式下,如果子线程无限迭代,主线程将永远无法等待,程序就会卡住。
说实话,这还挺尴尬的。

您应该了解守护线程和非守护线程的适用场景。
不要将重要任务变成守护线程,并且不要忘记添加超时。
尽管非守护线程是安全的,但如果子线程不终止,则可能会出现问题。