使用 Python 安装信号处理程序

发布于 2024-11-03 20:01:57 字数 1460 浏览 0 评论 0原文

(这个问题有一个后续这里

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

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 程序来 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)

(there is a follow up to this question here)

I am working on trying to write a Python based Init system for Linux but I'm having an issue getting signals to my Python init script. From the 'man 2 kill' page:

The only signals that can be sent to process ID 1, the init process,  are  those for which init has explicitly installed signal handlers.

In my Python based Init, I have a test function and a signal handler setup to call that function:

def SigTest(SIG, FRM):
    print "Caught SIGHUP!"

signal.signal(signal.SIGHUP, SigTest)

From another TTY (the init script executes sh on another tty) if I send a signal, it is completely ignored and the text is never printed. kill -HUP 1

I found this issue because I wrote a reaping function for my Python init to reap its child processes as they die, but they all just zombied, it took awhile to figure out Python was never getting the SIGCHLD signal. Just to ensure my environment is sane, I wrote a C program to fork and have the child send PID 1 a signal and it did register.

How do I install a signal handler the system will acknowledge if signal.signal(SIG, FUNC) isn't working?

Im going to try using ctypes to register my handler with C code and see if that works, but I rather a pure Python answer if at all possible.

Ideas?

( I'm not a programmer, Im really in over my head here :p )

Test code below...

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

莫相离 2024-11-10 20:01:57

信号处理程序主要在 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()

在我的系统上运行。

Signal handlers mostly work in Python. But there are some problems. One is that your handler won't run until the interpreter re-enters it's bytecode interpreter. if your program is blocked in a C function the signal handler is not called until it returns. You don't show the code where you are waiting. Are you using signal.pause()?

Another is that if you are in a system call you will get an exception after the singal handler returns. You need to wrap all system calls with a retry handler (at least on Linux).

It's interesting that you are writing an init replacement... That's something like a process manager. The proctools code might interest you, since it does handle SIGCHLD.

By the way, this code:

import signal

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

signal.signal(signal.SIGHUP, SigTest)

while True:
    signal.pause()

Does work on my system.

一梦等七年七年为一梦 2024-11-10 20:01:57
import signal

from signal import api_client

# Create an instance of the Signal API client

sig = api_client('YOUR_API_KEY')

# Send a message using the Signal API

sig.send_message(recipient='TOKEN', message='Hello world!')
import signal

from signal import api_client

# Create an instance of the Signal API client

sig = api_client('YOUR_API_KEY')

# Send a message using the Signal API

sig.send_message(recipient='TOKEN', message='Hello world!')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文