使用Python安装信号处理程序

时间:2011-04-29 01:11:06

标签: python c linux init signal-handling

(此问题的后续跟进here

我正在尝试为Linux编写一个基于Python的Init系统,但是我在向Python init脚本发送信号时遇到了问题。从'man 2 kill'页面:

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),它将被完全忽略,并且永远不会打印文本。 kill -HUP 1

我发现了这个问题,因为我为我的Python init写了一个收割函数,以便在它们死亡时收获它们的子进程,但它们都只是僵尸,需要一段时间才能弄清楚Python从未得到SIGCHLD信号。为了确保我的环境是理智的,我写了一个C程序来分叉并让孩子发送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)

1 个答案:

答案 0 :(得分:1)

信号处理程序主要使用Python。但是有一些问题。一个是在解释器重新输入字节码解释器之前,你的处理程序不会运行。如果您的程序在C函数中被阻止,则在返回之前不会调用信号处理程序。您不会在等待的位置显示代码。你在使用signal.pause()?

另一个是如果你在系统调用中,你将在单一处理程序返回后得到一个异常。您需要使用重试处理程序包装所有系统调用(至少在Linux上)。

有趣的是,你正在编写一个init替换...这就像一个流程管理器。 proctools代码可能会让您感兴趣,因为它确实处理SIGCHLD。

顺便说一下,这段代码:

import signal

def SigTest(SIG, FRM):
    print "SIGINT Caught"

signal.signal(signal.SIGHUP, SigTest)

while True:
    signal.pause()

可以在我的系统上运行。