1

(这里有对这个问题的跟进)

我正在尝试为 Linux 编写基于 Python 的 Init 系统,但在获取 Python 初始化脚本的信号时遇到问题。从'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(初始化脚本在另一个 tty 上执行 sh)发送信号,它会被完全忽略,并且永远不会打印文本。kill -HUP 1

我发现这个问题是因为我为我的 Python init 编写了一个 reaping 函数,以便在其子进程死亡时获取它们,但它们都只是僵死了,花了一段时间才发现 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)
4

1 回答 1

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()

在我的系统上工作。

于 2011-04-29T01:58:11.093 回答