使用Python安装信号处理程序
(这个问题有后续讨论,可以在这里查看)
我正在尝试为Linux编写一个基于Python的初始化系统,但在将信号发送到我的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初始化中,我设置了一个测试函数和一个信号处理器来调用这个函数:
def SigTest(SIG, FRM):
print "Caught SIGHUP!"
signal.signal(signal.SIGHUP, SigTest)
从另一个TTY(我的初始化脚本在另一个tty上执行sh)发送信号时,它完全被忽略,文本从未打印出来。比如我用命令kill -HUP 1
。
我发现这个问题是因为我为我的Python初始化编写了一个回收函数,用来处理它的子进程在死亡时的情况,但这些子进程都变成了僵尸进程,花了我一段时间才搞明白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)
2 个回答
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!')
当然可以!请把你想要翻译的内容发给我,我会帮你把它变得更简单易懂。
信号处理器在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()
在我的系统上是可以工作的。