为了账号安全,请及时绑定邮箱和手机立即绑定

Python 和信号处理程序

Python 和信号处理程序

慕雪6442864 2021-06-08 17:47:51
我需要对 python 中的信号处理程序进行一些澄清,因为我不完全了解它们是如何工作的,我如何使用它们以及有哪些限制。我打算在 linux 上使用 USR 信号,以便与作为服务在后台运行的 python 程序进行通信。我发现,正如预期的那样,我发送的信号似乎以异步方式立即处理。因此,我曾经认为注册的信号处理程序在他们自己的线程中运行,我认为这可以解释为什么以下代码Signal handler called with signal 10在循环中发送信号时会一次打印多行#!/usr/bin/python3.5# This is the file signal_example.pyimport signal, time, osdef handler(signum, frame):    print('Signal handler called with signal', signum)    time.sleep(20)signal.signal(signal.SIGUSR1, handler)time.sleep(100)#!/usr/bin/bashfor ((i=0;i<100;i=i+1)); do     killall -s SIGUSR1 signal_example.py; done但是,文档说明(https://docs.python.org/3.4/library/signal.html)“Python信号处理程序始终在主 Python 线程中执行,即使信号是在另一个线程中接收到的。”。此外,对于上述示例,我没有看到我的系统上运行单独的线程。我现在想知道,我使用信号的方法的实际含义和限制是什么,以及我如何正确地做相关的事情,例如被调用的信号处理程序的实例之间的通信。例如,在某些情况下,我希望能够延迟信号处理程序中某些代码的执行,直到处理完以前的相同类型的信号。此外,我不明白将“并行”处理多少信号以及“队列”已满时会发生什么......我一直在研究 Pyhton 的asyncio,它似乎提供了对异步代码的一些控制,并且还带来了自己的注册信号处理程序的方式。它似乎提供了一些帮助,但是,它似乎对我没有多大帮助,因为我看到的行为(收到信号时几乎处理了它们)实际上是我想要的。asyncio我所看到的信号处理程序的使用似乎是在事件循环中执行信号。在我开始的部分阻塞代码中,这可能为时已晚。我可以在单独的线程中运行其中的一些(使用相应的asyncio函数),但不能使整个代码成为非阻塞的。
查看完整描述

1 回答

?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

我打算在 linux 上使用 USR 信号,以便与作为服务在后台运行的 python 程序进行通信。

这听起来真是个坏主意。以下是几个原因:

  • Unix 信号是异步传递的,这意味着您可以在任何库代码运行时获取信号,例如在malloc调用过程中。出于这个原因,只有少数函数是异步信号安全的,即从信号处理程序调用是安全的。Python 代码根本无法在信号处理程序内部执行,因此设置的处理程序signal.signal不执行 Python 函数,而只是设置一个全局标志。该标志由执行 Python 处理程序函数的主线程不时检查。这意味着不能保证立即传递信号,即您不能依赖操作系统提供的信号传递保证。

  • 信号可能在前一个信号的处理程序执行期间到达。这就是为什么您会看到打印多行的原因,这是信号处理程序本身被信号中断并重新输入的产物。

  • 除非您使用专门的 POSIX 调用设置信号处理程序(并且使用这些调用设置的处理程序不能直接执行 Python 代码),否则信号不会排队。即使当它们排队时,除了非实时信号,生成和传递之间的信号顺序也不会保留。

  • 信号与多线程代码的交互非常糟糕,即使在纯 C 中也是如此。

如果您有一个需要与之通信的服务,您可以拥有一个从命名管道读取或侦听套接字的线程。写入管道或打开套接字将作为进程的信号。这也允许将附加信息传递给服务。


查看完整回答
反对 回复 2021-06-16
  • 1 回答
  • 0 关注
  • 153 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信