Python中的信号处理

4 投票
4 回答
6891 浏览
提问于 2025-04-15 18:38

在我的程序里,有很多线程在运行,我想打断主线程,让它异步地做点事情。为此,我设置了一个处理器,并给主进程发送了一个SIGUSR1信号——下面是代码:

def SigUSR1Handler(signum, frame):

    self._logger.debug('Received SIGUSR1')

    return

signal.signal(signal.SIGUSR1, SigUSR1Handler)

[signal.signal(signal.SIGUSR1, signal.SIG_IGN)]

在这种情况下,所有线程和主进程都停止了——从“C”语言的角度来看,这让我感到意外——我希望线程在收到信号后能继续运行。如果我用SIG_IGN代替,所有东西就能正常继续。

有人能告诉我该怎么做吗?也许我需要手动处理一下“帧”,才能回到之前的状态……不过这只是个猜测,提前谢谢大家。


感谢你们的帮助。

再多解释一下,我有一些线程实例正在将字符串信息写入一个套接字,同时这些信息也会输出到一个文件。这些线程各自运行自己的定时器,所以它们独立地将输出写入套接字。当程序运行时,我也能在标准输出上看到它们的输出,但一旦我看到信号的调试信息,所有输出就会停止。

我需要这些线程不断发送信息,但我也希望主程序能够接收命令,这样它就能同时做其他事情。我原以为只需从命令行发送一个信号就能触发这个操作。

4 个回答

0

你可能应该使用一个叫做 threading.Condition 的变量,而不是发送信号。让你的主线程在每次循环时检查这个变量,如果它被设置了,就执行特定的操作。

如果你还是想用信号,那你可能需要改用 subprocess,而不是线程,因为你的问题很可能是由于 GIL(全局解释器锁)造成的。

1

我来简单回答一下我自己的问题:

在我第一次尝试的时候,我在主线程里用time.sleep(run_time)来控制线程运行的时间,直到它们被停止。通过调试,我发现这个睡眠循环似乎在信号处理程序返回后就退出了,所以所有的东西都正常关闭,但却提前结束了!

我把睡眠替换成了一个while循环,这样在信号处理程序返回后就不会跳出来了,所以我的线程可以继续运行。这解决了问题,但我对sleep()的行为还是有点困惑。

2

混合使用信号和线程总是有点危险。你描述的情况不应该发生。Python 只在主线程中处理信号。如果操作系统把信号发送到了其他线程,那些线程可能会被短暂打断(比如在执行系统调用时),但它们不会执行信号处理程序。主线程会在下一个机会执行信号处理程序。

当你发送信号时,你的线程(包括主线程)实际上在做什么?你是怎么注意到它们都“停止”了?是短暂的暂停(这可以通过主线程在处理信号前需要获取全局解释器锁来解释)还是整个进程完全崩溃了?

撰写回答