Cha*_*ker 5 python subprocess kill kill-process
我一直在尝试找出如何启动不同的子流程实例,然后杀死它们然后创建新的实例。父python进程从不执行,只会杀死子进程。我在SO上跟踪了很多链接,但是一旦父python进程结束,我就会不断收到以下消息:
F/Users/Lucifer/miniconda3/envs/rltp/lib/python3.6/subprocess.py:761: ResourceWarning: subprocess 40909 is still running ResourceWarning, source=self)
Run Code Online (Sandbox Code Playgroud)
这似乎很有趣,因为我做到了,ps但是却一无所获:
PID TTY TIME CMD
7070 ttys001 0:00.06 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp Lucifer
7072 ttys001 0:00.61 -bash
17723 ttys002 0:00.06 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp Lucifer
17725 ttys002 0:00.06 -bash
38586 ttys002 0:00.16 sertop --no_init
Run Code Online (Sandbox Code Playgroud)
我只想开始一个过程:
self.serapi = subprocess.Popen(['sertop','--no_init'],
stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,
preexec_fn=os.setsid,shell=True
,)
Run Code Online (Sandbox Code Playgroud)
并杀死它:
os.killpg(os.getpgid(self.serapi.pid), signal.SIGTERM)
Run Code Online (Sandbox Code Playgroud)
上面的代码本质上是从最上面的答案复制的:
但我不确定为什么会收到此消息。我是否成功终止了子进程?我计划启动并杀死其中许多人。
注意我不知道或不需要shell=True。我只是复制了那个,就是我发布的答案/问题的答案。我宁愿没有那个参数。
根据我尝试的答案:
def kill(self):
self.serapi.wait()
#self.serapi.kill()
self.serapi.terminate()
#os.killpg(os.getpgid(self.serapi.pid), signal.SIGTERM)
#self.serapi.wait()
Run Code Online (Sandbox Code Playgroud)
以及上述内容的不同排列方式,但似乎没有任何效果。有什么建议吗?
该ResourceWarning: subprocess N is still running警告来自__del__该类的方法subprocess.Popen。
如果您查看该方法的源代码,您将看到以下评论:
# Not reading subprocess exit status creates a zombie process which
# is only destroyed at the parent python process exit
_warn("subprocess %s is still running" % self.pid,
ResourceWarning, source=self)
Run Code Online (Sandbox Code Playgroud)
解决方案是确保您调用wait()子进程。
有关更多背景信息,请参阅手册页的“注释”部分。wait(2)
在 Python 中,处理这种情况的最简单方法是跟踪Popen您创建的所有对象,并确保有东西wait()直接或间接地调用它们。
或者,您可以安装一个SIGCHLD忽略SIGCHLD事件的处理程序;那么你的子进程将立即消失,但你现在将无法调用它们wait()。另请参阅如何防止僵尸子进程?以及如何处理 SIGCHLD?