在Python中,当父进程崩溃时杀死子进程

14

我正在尝试编写一个使用Python程序来测试用C语言编写的服务器。Python程序使用subprocess模块启动已编译的服务器:

pid = subprocess.Popen(args.server_file_path).pid

这个方法运行良好,但是如果Python程序因错误而意外终止,那么派生的进程将会保持运行状态。我需要一种方法来确保如果Python程序意外退出,服务器进程也会被杀死。

更多细节:

  • 仅适用于Linux或OSX操作系统
  • 服务器代码无法以任何方式修改

由于错误。-- 是什么类型的错误? - mgilson
网络错误,键盘中断等。 - charliehorse55
1
supervisor 是一个用 Python 编写的开源进程管理守护程序。如果您有时间,不妨查看一下它的源代码。 - Phil Frost
重复的问题:https://dev59.com/xXI-5IYBdhLWcg3wYnOQ - Thomas Ahle
1个回答

21

我会使用atexit.register函数来注册一个终止进程的函数:

import atexit
process = subprocess.Popen(args.server_file_path)
atexit.register(process.terminate)
pid = process.pid

也许是这样:
import atexit
process = subprocess.Popen(args.server_file_path)
@atexit.register
def kill_process():
    try:
        process.terminate()
    except OSError:
        pass #ignore the error.  The OSError doesn't seem to be documented(?)
             #as such, it *might* be better to process.poll() and check for 
             #`None` (meaning the process is still running), but that 
             #introduces a race condition.  I'm not sure which is better,
             #hopefully someone that knows more about this than I do can 
             #comment.

pid = process.pid

请注意,如果您做了一些不好的事情导致Python以非正常的方式死亡(例如通过os._exit或者导致SegmentationFaultBusError),这将无法帮助您。

@ire_and_curses -- 感谢您添加链接,非常感谢。 - mgilson
7
“nasty case”是最有趣的一个。 - vak
1
我在https://dev59.com/5F8e5IYBdhLWcg3wo7iE#25634723中提供了一个“恶劣情况”的选项,但它在这里没有帮助(它需要访问客户端源代码)。 - Bas Wijnen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接