使用 signal.CTRL_C_EVENT 杀死子进程而不杀死主进程

时间:2021-02-10 19:22:24

标签: python python-unittest

如何在不同时杀死 ma​​in 的情况下杀死子进程?

我有一个只能用 signal.CTRL_C_EVENT 终止的子进程。执行标准 os.kill(my_pid, signal.CTRL_C_EVENT) 会终止进程,但也会导致我的主要进程死掉,尽管有不同的网络 pid。

我的最终目标是从单元测试中创建子流程,因此我需要单元测试在通过所有测试后返回 sys.exit(0)

child.py

from time

while True:
  print "I am alive"
  time.sleep(0.5)

parent.py

import os
import signal
import subprocess
import time

p = subprocess.Popen(["child.py"], shell=True)
time.sleep(5)
os.kill(p.pid, signal.CTRL_C_EVENT)

print("This line doesn't print because the main thread dies")

::: 更新:::

我正在尝试在 Windows 中运行它。删除 shell=True 没有明显效果。我在 parent.py 中看到 KeyboardInterrupt 错误

Traceback (most recent call last)    
    File "parent.py", line 23, in <module>
KeyboardInterrupt

以下所有方法都会导致相同的行为

  • os.kill
  • psutil.Process(os.getpid()).children() 上发送信号
  • subprocess.call(['taskkill', ...

2 个答案:

答案 0 :(得分:0)

我认为您使用的是 Windows。这是这里的一个重要区别。您似乎也在使用 Python2。

在 Windows 上,os.kill 有一些非常奇怪的行为。我什至建议不要尝试使用它,除非你想让自己头疼。尝试使用 psutil(在父级中):

    children = psutil.Process(os.getpid()).children()
    for c in children:
        c.send_signal(signal.CTRL_C_EVENT)
    psutil.wait_procs(children)

或者,您可以调用 taskkill

subprocess.call(['taskkill', '/PID', str(child.pid)])

答案 1 :(得分:0)

您可以尝试将字节 0x03 发送到子进程的标准输入 (stdin)。这是用于指示 Ctrl+C 信号的字节。