Python:如何防止子进程接收CTRL-C/Control-C/SIGINT [英] Python: How to prevent subprocesses from receiving CTRL-C / Control-C / SIGINT

查看:222
本文介绍了Python:如何防止子进程接收CTRL-C/Control-C/SIGINT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为外壳中运行的专用服务器的包装程序工作.包装器通过子进程产生服务器进程,并观察其输出并对之作出反应.

I am currently working on a wrapper for a dedicated server running in the shell. The wrapper spawns the server process via subprocess and observes and reacts to its output.

必须为专用服务器明确提供命令以正常关闭.因此,CTRL-C一定不能到达服务器进程.

The dedicated server must be explicitly given a command to shut down gracefully. Thus, CTRL-C must not reach the server process.

如果我捕获了KeyboardInterrupt异常或覆盖了python中的SIGINT处理程序,则服务器进程仍会收到CTRL-C并立即停止.

If I capture the KeyboardInterrupt exception or overwrite the SIGINT-handler in python, the server process still receives the CTRL-C and stops immediately.

所以我的问题是: 如何防止子进程接收CTRL-C/Control-C/SIGINT?

So my question is: How to prevent subprocesses from receiving CTRL-C / Control-C / SIGINT?

推荐答案

#python IRC-Channel(Freenode)中的某人通过指出 subprocess.Popen的 preexec_fn 参数来帮助我. (...):

Somebody in the #python IRC-Channel (Freenode) helped me by pointing out the preexec_fn parameter of subprocess.Popen(...):

如果 preexec_fn 设置为可调用 对象,该对象将在 子进程就在 孩子被处决. (仅限Unix)

If preexec_fn is set to a callable object, this object will be called in the child process just before the child is executed. (Unix only)

因此,以下代码解决了该问题(仅UNIX):

Thus, the following code solves the problem (UNIX only):

import subprocess
import signal

def preexec_function():
    # Ignore the SIGINT signal by setting the handler to the standard
    # signal handler SIG_IGN.
    signal.signal(signal.SIGINT, signal.SIG_IGN)

my_process = subprocess.Popen(
    ["my_executable"],
    preexec_fn = preexec_function
)

注意:实际上并没有阻止信号到达子流程.相反,上面的 preexec_fn 会覆盖信号的默认处理程序,以便忽略该信号.因此,如果子进程再次覆盖 SIGINT 处理程序,则此解决方案 可能不起作用.

Note: The signal is actually not prevented from reaching the subprocess. Instead, the preexec_fn above overwrites the signal's default handler so that the signal is ignored. Thus, this solution may not work if the subprocess overwrites the SIGINT handler again.

另一个说明::该解决方案适用于各种子流程,即它也不限于使用Python编写的子流程.例如,我为其编写包装程序的专用服务器实际上是用Java编写的.

Another note: This solution works for all sorts of subprocesses, i.e. it is not restricted to subprocesses written in Python, too. For example the dedicated server I am writing my wrapper for is in fact written in Java.

这篇关于Python:如何防止子进程接收CTRL-C/Control-C/SIGINT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆