为什么杀死这个子进程会引发 ProcessLookupError?

beg*_*ner 3 python subprocess kill python-3.3 python-3.4

我不明白什么时候需要杀死子进程。

for package in server.packages:
    n = subprocess.Popen(['which', package], stdout=subprocess.DEVNULL)
    n.wait()
    if n.returncode != 0:
        n.kill()
        <some other code>
Run Code Online (Sandbox Code Playgroud)

我收到错误(使用 Python3):

ProcessLookupError: [Errno 3] No such process
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释我什么时候子进程自杀以及什么时候需要手动完成?

Pet*_*tri 5

在 Python 中,Popen.wait是等待子进程终止的阻塞调用。所以通常不需要在调用wait返回后杀死子进程。请参阅有关Popen.wait() 的Python 文档。

现在,如果您了解它的工作原理,您会发现您的代码失败了,因为在某些时候Popen.returncode返回了一个非零值,然后您尝试终止一个不再存在的进程。

这就是 aProcessLookupError被提出的原因。

现在,正如这里的另一个答案所指出的那样,返回的值可能是None,这表明子进程可能存在(可能是操作系统特定的)问题并且可以检查。Python文档仅仅状态None表示该过程仍在运行(负值也是可能的;见文档的详细信息)。

除此之外,如果出于某种原因需要终止仍在运行的子进程,则必须使用以下方法设置并捕获超时:

   try:
      # time out in five seconds
      n.wait(timeout=5)
   except TimeOutExpired:
      # you can use kill, terminate or send_signal method; see the docs
      n.kill()
Run Code Online (Sandbox Code Playgroud)

... 或者,根本不使用wait:相反,当您在代码中执行其他操作时让子进程运行,然后稍后将其杀死:

   import os

   processes = []
   for package in server.packages:
      n = subprocess.Popen(['which', package], stdout=subprocess.DEVNULL)
      processes.append(n)

   <some other code while the subprocesses run (and possibly terminate)>

   for p in processes:
      try:
          p.kill()
      except OSError:
          # silently fail if the subprocess has exited already
          pass
Run Code Online (Sandbox Code Playgroud)

如果您只想检查进程是否处于活动状态怎么办?不幸的是,Python stdlib 没有一种好的、方便的方法来检查进程是否正在运行。但是,可以使用第三方库psutil方便地完成。有了它,检查进程是否存在就像:

   pid = n.pid # where n is a subprocess.Popen object from above examples
   import psutil
   psutil.pid_exists(pid) # returns True or False
Run Code Online (Sandbox Code Playgroud)