如何在无需线程配合的情况下中断或发送信号给Python线程?
之前我以为在Python中不可能非合作地中断一个线程。举个例子,可能是主线程想要立即取消其他线程的运行。但是,从信号文档来看:
Python的信号处理程序总是在主Python线程中执行,即使信号是在其他线程中接收到的。这意味着信号不能用作线程间的通信方式。
……不过……
https://youtu.be/9OOJcTp8dqE?si=_GVmIcCGX9JTawXZ&t=1872
有说法是:
[……] Python已经有一种机制,可以请求线程处理异步信号和异常……
我看到Java有Thread.interrupt()这个方法,但Python没有。
那么,现在在Python中是否可能做到这一点呢?
1 个回答
总结:没有办法做到这一点!
详细说明:
你希望线程如何“非合作”地响应呢?
视频中提到的机制,其实是Python运行时内部使用的机制,主要用于一些像讲座中提到的黑科技。
回到应该如何工作的问题——信号处理器是一个注册的回调函数,即使这对Python代码开放了一个每个线程的信号回调,想要实现这个功能也比简单地从一个队列中读取指令要复杂得多。(而且,注册一个每个线程的回调函数,根本不能算是“非合作”的方式)。
总之,不行。一旦一个Python线程开始运行,它会一直运行,直到“没有代码可执行”(也就是从启动线程时传入的“目标”函数返回)。你可以通过从一个队列中消费元素来强制这个过程,以实现线程间的通信,并在队列上给出一个适当的信号,抛出异常或跳出工作循环。(这个模式被称为“毒丸”)。这就是它的工作方式。
在Python 3.12中,可以使用“子解释器”,这些子解释器是没有全局解释器锁(GIL)的,逻辑也是一样的——不过入口点不是一个函数,而是一段代码字符串:如果从字符串中评估的代码“结束”,解释器就会闲置——你必须明确地关闭它。但除了关闭一个闲置的子解释器外,没有其他机制可以使用。(虽然可以调用关闭一个非闲置的子解释器,但这很可能会导致Python运行时崩溃)。