Python和信号处理程序

Python和信号处理程序,python,signals,python-multithreading,python-asyncio,Python,Signals,Python Multithreading,Python Asyncio,我需要一些关于python中的信号处理程序的澄清,因为我不清楚它们是如何工作的,如何使用它们,以及它们的限制是什么 我打算在linux上使用USR信号,以便与作为服务在后台运行的python程序通信 我发现,正如预期的那样,我发送的信号似乎立即以异步方式进行处理 因此,我过去认为注册的信号处理程序在它们自己的线程中运行,我认为这可以解释为什么在循环中发送信号时,下面的代码会一次打印多行用信号10调用的信号处理程序 #!/usr/bin/python3.5 # This is the file s

我需要一些关于python中的信号处理程序的澄清,因为我不清楚它们是如何工作的,如何使用它们,以及它们的限制是什么

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

我发现,正如预期的那样,我发送的信号似乎立即以异步方式进行处理

因此,我过去认为注册的信号处理程序在它们自己的线程中运行,我认为这可以解释为什么在循环中发送信号时,下面的代码会一次打印多行用信号10调用的
信号处理程序

#!/usr/bin/python3.5
# This is the file signal_example.py

import signal, time, os

def handler(signum, frame):
    print('Signal handler called with signal', signum)
    time.sleep(20)

signal.signal(signal.SIGUSR1, handler)

time.sleep(100)


#!/usr/bin/bash
for ((i=0;i<100;i=i+1)); do 
    killall -s SIGUSR1 signal_example.py; 
done
#/usr/bin/python3.5
#这是signal_example.py文件
导入信号、时间、操作系统
def处理器(信号、帧):
打印('使用信号调用信号处理程序',signum)
时间。睡眠(20)
signal.signal(signal.SIGUSR1,处理程序)
时间。睡眠(100)
#!/usr/bin/bash
对于((i=0;i
我打算在linux上使用USR信号,以便与作为服务在后台运行的python程序通信

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

    <> LI>< UNIX信号异步传递,这意味着当任何库代码运行时,您可以得到信号,例如在“代码> MALLC/调用”的中间。由于这个原因,只有少数函数是安全的,可以从信号处理程序调用。Python代码根本不能在信号处理程序内执行,因此处理程序集By
    signal.signal
    不执行Python函数,只是设置一个全局标志。该标志由执行Python处理程序函数的主线程不时检查。这意味着不能保证信号会立即传递,即不能依赖提供的信号传递保证通过操作系统

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

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

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


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

谢谢您的回答。我从您的描述中获得的图片iption是指从我的Python脚本生成的二进制代码包含对该信号标志的显式检查。我假设信号处理程序不会中断
malloc
(这里您似乎指的是UNIX)一个信号的接收并不能阻止正在运行的信号处理程序,但是它可以与它们和主程序流进行交互。一个明显的问题是,如果考虑在每个信号处理程序中手动启动一个新线程是有意义的。如果有的话,你能指给我一个参考atomic Python吗?这里管道或套接字用于与python脚本的进程间通信?@highscigue信号处理程序肯定会中断
malloc
——另一种选择是每个
malloc
阻塞信号并恢复它们,这需要两次到内核的往返并影响性能。但你不在乎这在Python中是因为(如回答中所讨论的)Python不会直接从处理程序运行代码。也许我仍然不明白。我一直认为您的意思是说UNIX信号处理程序(低级)会中断
malloc
,但调用的Python处理程序函数只有在
malloc
完成时才会运行(一旦看到设置了信号处理程序标志)。我会假设,对于信号的第一个效果,
malloc
将需要处理,因为它是一个标准的UNIX,我认为许多进程都会实现。@highscigue,这就是我的意思,是的。问题是,在Python中注册的信号处理程序将比在C中注册的信号处理程序运行得晚。换句话说,如果原始交付速度是使用信号的动机在Python中是看不到的。