有没有办法让os.killpg不会杀死调用它的脚本?

时间:2014-05-22 15:50:39

标签: python subprocess

我打开了一个子进程,调用其他进程。

我使用os.killpg(os.getpgid(subOut.pid), signal.SIGTERM)来杀死整个组,但这也会杀死python脚本。即使我从第二个python脚本调用带有os.killpg的python脚本,也会杀死第二个脚本。有没有办法让os.killpg不停止脚本?

另一个解决方案是单独杀死每个子进程1进程。但是,即使使用

p = psutil.Process(subOut.pid)
child_pid = p.children(recursive=True)
for pid in child_pid:
    os.kill(pid.pid, signal.SIGTERM)

没有正确地给我所有孩子的pids。

你知道他们说了什么......不要杀掉那个叫你的剧本......

3 个答案:

答案 0 :(得分:4)

回答得有点晚了,但是由于google在寻找相关问题时将我带到了这里:您的脚本被杀死的原因是默认情况下,其子级将继承其组ID。但是您可以告诉subprocess.Popen为您的子流程创建一个新的流程组。尽管有点棘手:您必须为os.setpgrp参数传递preexec_fn。这将在新创建的(派生的)进程中调用setpgrp(不带任何参数)(在执行此操作之前),这会将新进程的gid设置为新进程的pid(因此创建一个新组)。该文档提到它可能会在多线程代码中死锁。另外,您可以使用start_new_session=True,但这不仅会创建一个新的进程组,而且还会创建一个新的会话。 (这意味着,如果您在脚本运行时关闭终端会话,则子级将不会终止。这可能是问题,也可能不是问题。)

请注意,如果您在Windows上,只需在subprocess.CREATE_NEW_PROCESS_GROUP参数中传递creationflag

详细内容如下:

subOut = subprocess.Popen(['your', 'subprocess', ...], preexec_fn=os.setpgrp)

# when it's time to kill
os.killpg(os.getpgid(subOut.pid), signal.SIGTERM)

答案 1 :(得分:0)

创建一个进程组,其中包含被调用进程的所有直接子进程,如下所示:

p1 = subprocess.Popen(cmd1)
os.setpgrp(p1.pid, 0) #It will create process group with id same as p1.pid
p2 = subprocess.Popen(cmd2)
os.setpgrp(p2.pid, os.getpgid(p1.pid))

pn = subprocess.Popen(cmdn)
os.setpgrp(pn.pid, os.getpgid(p1.pid))

#Kill all the children and their process tree using following command
os.killpg(os.getpgid(p1.pid), signal.SIGKILL)

除了自己的进程外,它会杀死整个进程树。

答案 2 :(得分:0)

上面的atleta答案对我有用,但是Popen调用中的preexec_fn参数应该是setpgrp,而不是setgrp:

subOut = subprocess.Popen(['your', 'subprocess', ...], preexec_fn=os.setpgrp)

我将其发布为答案,而不是对atleta的答案发表评论,因为我还没有评论权限。