使用Python安装信号处理程序
(这个问题还有后续问题) 我正在努力为Linux编写一个基于Python的Init系统,但在获取Python Init脚本的信号时遇到了问题。从“杀人2”页面:使用Python安装信号处理程序,python,c,linux,init,signal-handling,Python,C,Linux,Init,Signal Handling,(这个问题还有后续问题) 我正在努力为Linux编写一个基于Python的Init系统,但在获取Python Init脚本的信号时遇到了问题。从“杀人2”页面: The only signals that can be sent to process ID 1, the init process, are those for which init has explicitly installed signal handlers. 在基于Python的Init中,我有一个测试函数和一个信号处
The only signals that can be sent to process ID 1, the init process, are those for which init has explicitly installed signal handlers.
在基于Python的Init中,我有一个测试函数和一个信号处理程序设置来调用该函数:
def SigTest(SIG, FRM):
print "Caught SIGHUP!"
signal.signal(signal.SIGHUP, SigTest)
从另一个TTY(init脚本在另一个TTY上执行sh)如果我发送一个信号,它将被完全忽略,并且永远不会打印文本<代码>杀死-HUP 1
我发现这个问题是因为我为我的Python init编写了一个收获函数,在子进程死亡时收获它们,但它们都只是僵尸,花了一段时间才发现Python从来没有得到SIGCHLD信号。为了确保我的环境正常,我编写了一个C程序来fork,让孩子给PID 1发送一个信号,它确实注册了
如果signal.signal(SIG,FUNC)
不工作,系统将确认如何安装信号处理程序
我将尝试使用ctypes用C代码注册我的处理程序,看看这是否有效,但如果可能的话,我宁愿选择纯Python的答案
想法
(我不是一个程序员,我真的很糊涂:p)
测试代码如下
import os
import sys
import time
import signal
def SigTest(SIG, FRM):
print "SIGINT Caught"
print "forking for ash"
cpid = os.fork()
if cpid == 0:
os.closerange(0, 4)
sys.stdin = open('/dev/tty2', 'r')
sys.stdout = open('/dev/tty2', 'w')
sys.stderr = open('/dev/tty2', 'w')
os.execv('/bin/ash', ('ash',))
print "ash started on tty2"
signal.signal(signal.SIGHUP, SigTest)
while True:
time.sleep(5.0)
信号处理程序主要在Python中工作。但也存在一些问题。一个是,在解释器重新进入字节码解释器之前,处理程序不会运行。如果您的程序在C函数中被阻塞,信号处理程序在返回之前不会被调用。在等待的位置不显示代码。是否正在使用signal.pause() 另一个原因是,如果您在系统调用中,那么在信号处理程序返回后,您将得到一个异常。您需要使用重试处理程序包装所有系统调用(至少在Linux上) 有趣的是,您正在编写一个init替换。。。这有点像流程管理器。您可能会对该代码感兴趣,因为它确实处理SIGCHLD 顺便说一下,这个代码:
import signal
def SigTest(SIG, FRM):
print "SIGINT Caught"
signal.signal(signal.SIGHUP, SigTest)
while True:
signal.pause()
在我的系统上工作。信号处理程序主要在Python中工作。但也存在一些问题。一个是,在解释器重新进入字节码解释器之前,处理程序不会运行。如果您的程序在C函数中被阻塞,信号处理程序在返回之前不会被调用。在等待的位置不显示代码。是否正在使用signal.pause() 另一个原因是,如果您在系统调用中,那么在信号处理程序返回后,您将得到一个异常。您需要使用重试处理程序包装所有系统调用(至少在Linux上) 有趣的是,您正在编写一个init替换。。。这有点像流程管理器。您可能会对该代码感兴趣,因为它确实处理SIGCHLD 顺便说一下,这个代码:
import signal
def SigTest(SIG, FRM):
print "SIGINT Caught"
signal.signal(signal.SIGHUP, SigTest)
while True:
signal.pause()
在我的系统上工作。我没有使用signal.pause(),我会试试。我用我使用的测试代码编辑了这篇文章Ha,sleep()函数将阻止信号处理程序,直到它完成。这就是为什么我要写一个模块。当中断时,它调用C API PyErr_CheckSignals。这允许调用信号处理程序。将sleep()更改为signal.pause()也不起作用。我还尝试将sleep()改为0.01(以便使它看起来更瞬时),但信号仍然没有被捕捉到。内核?必须封锁所有信号。。。C程序和Python程序安装信号处理程序的方式肯定有所不同,它处理信号处理程序的方式也有所不同。正如我所说,我确实在Python中使用了信号,但是我做了一些更改。在编译的C程序和Python脚本上执行strace,这两个脚本都设置了信号处理程序,看起来它们都使用了系统调用“rt_sigaction”。然而,python程序似乎试图为相同的信号设置2x,第一次是空值,而不是稍后使用函数
rt_-sigaction(SIGINT,NULL,{SIG_-DFL,[],0},8)=0
rt_-sigaction(SIGINT,{0x4d7270,[],SA_-RESTORER,0x7f928fce0b40},{SIG_-DFL,[],0},8)=0
。可能它只注册了第一个?我没有使用signal.pause(),我会试试。我用我使用的测试代码编辑了这篇文章Ha,sleep()函数将阻止信号处理程序,直到它完成。这就是为什么我要写一个模块。当中断时,它调用C API PyErr_CheckSignals。这允许调用信号处理程序。将sleep()更改为signal.pause()也不起作用。我还尝试将sleep()改为0.01(以便使它看起来更瞬时),但信号仍然没有被捕捉到。内核?必须封锁所有信号。。。C程序和Python程序安装信号处理程序的方式肯定有所不同,它处理信号处理程序的方式也有所不同。正如我所说,我确实在Python中使用了信号,但是我做了一些更改。在编译的C程序和Python脚本上执行strace,这两个脚本都设置了信号处理程序,看起来它们都使用了系统调用“rt_sigaction”。然而,python程序似乎试图为相同的信号设置2x,第一次是空值,而不是稍后使用函数rt_-sigaction(SIGINT,NULL,{SIG_-DFL,[],0},8)=0
rt_-sigaction(SIGINT,{0x4d7270,[],SA_-RESTORER,0x7f928fce0b40},{SIG_-DFL,[],0},8)=0
。也许它只记录了第一个?