Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何为子流程注册信号处理程序?_Python_Linux_Subprocess_Signals - Fatal编程技术网

Python 如何为子流程注册信号处理程序?

Python 如何为子流程注册信号处理程序?,python,linux,subprocess,signals,Python,Linux,Subprocess,Signals,添加一个信号处理器,例如 #!/usr/bin/python import subprocess as sp import signal import time def child_handler(sig, frame): print("SIGINT child received") def handler(sig, frame): print("SIGINT received") def preexec(): print("entering preexec")

添加一个信号处理器,例如

#!/usr/bin/python

import subprocess as sp
import signal
import time

def child_handler(sig, frame):
    print("SIGINT child received")

def handler(sig, frame):
    print("SIGINT received")

def preexec():
    print("entering preexec")
    signal.signal(signal.SIGINT, child_handler)
    #signal.signal(signal.SIGINT, signal.SIG_IGN)
    print("leaving preexec")

def signal_sending():
    signal.signal(signal.SIGINT, handler)
    p = sp.check_call(["bash", "process.sh"], preexec_fn=preexec)

if __name__ == "__main__":
    signal_sending()
使用
process.sh

#!/bin/sh

i=0

while [ 1 ]; do
sleep 0.1;
echo $i
i=$((i + 1))
done
不工作,因为CtrlC中断子进程(仅打印
SIGINT received
),但应打印
SIGINT received
SIGINT child received
,子进程继续运行

添加
signal.SIG\u IGN
使子对象保持不变,但这还不够,因为我需要为子对象编写自定义处理程序


我不在乎是否必须使用Python2.7或3.x来实现这一点。我使用的是Linux 4.3。

bash进程取代了forked
python
进程,因此它无法运行python回调
SIG\u IGN
适用于
SIGINT
,因为它在
exec()调用中幸存下来


如果您希望在按下Ctrl+C时运行一些Python代码;将其放入
处理程序()
(父级中的信号处理程序)。或者在bash中捕获相应的信号,并在
process.sh

Ahh中的信号上运行python子进程,我只是在上请求更好的信号处理文档。知道如何防止接收子进程的子进程的SIGINT吗?我正在尝试使用
apt get
生成
dpkg
,它本身会生成像
gpgv
这样的进程,并且由于子进程的子进程接收到SIGINT而中止。shell中的Ctrl+C将SIGINT发送到前台进程组(当前管道)中的所有进程。传递
preexec\u fn=os.setpgrp
以创建新的进程组,以避免将信号传播到子进程(及其子进程)。指定
preexec\u fn=os.setpgrp
会导致终端(
gnome terminal
xterm
)若要变得无响应,请期待在父进程(在我注册的自定义处理程序中)中处理的
SIGINT
。@KarlRichter:preexec_fn=os.setpgrp
的要点是,外壳中的某些信号不会传播到子进程,否则子进程将无法响应(因此,子进程不会被这些信号杀死)。这是您想要的:“防止子进程的子进程[Ctrl+C]接收SIGINT”.
os.setpgrp
不会产生无响应问题,如果它已经存在,则可能会暴露它:如果子进程可能被卡住,那么如果您[在Ctrl+C]上]删除了直接从shell杀死它的功能,则它看起来没有响应。如果仍然不清楚,请提出单独的问题