无知的 TonySeek

Yet Another Seeker

杀死 subprocess.Popen 的子子孙孙

Python 标准库 subprocess.Popen 是 shellout 一个外部进程的首选,它在 Linux/Unix 平台下的实现方式是 fork 产生子进程然后 exec 载入外部可执行程序。

于是问题就来了,如果我们需要一个类似“夹具”的子进程(比如运行 Web 集成测试的时候跑起来的那个被测试 Server), 那么就需要在退出上下文的时候清理现场,也就是结束被跑起来的子进程。

最简单粗暴的做法可以是这样:

process_fixture.py
 @contextlib.contextmanager
 def process_fixture(shell_args):
     proc = subprocess.Popen(shell_args)
     try:
         yield
     finally:
         # 无论是否发生异常,现场都是需要清理的
         proc.terminate()
         proc.wait()


 if __name__ == '__main__':
     with ...