为什么查杀此子进程会引发ProcessLookupError?

时间:2015-08-26 05:12:25

标签: python subprocess python-3.4 python-3.3 kill

我无法理解何时需要杀死子进程。

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

我收到错误(使用Python3):

ProcessLookupError: [Errno 3] No such process

当子进程自杀以及我需要手动执行时,有人可以解释一下吗?

3 个答案:

答案 0 :(得分:4)

在Python中,Popen.wait是一个阻塞调用,等待子进程终止。因此,在调用wait之后通常无需终止子进程。请参阅Popen.wait()上的Python文档。

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

这就是引发ProcessLookupError的原因。

现在,正如另一个答案所指出的那样,返回的值可能是None,这表示子进程可能(可能是特定于操作系统)的问题,可以检查。 None表示进程仍在运行的Python文档merely state(也可能是负值;有关详细信息,请参阅文档)。

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

   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()

...或者,根本不使用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

如果您想检查流程是否存在,该怎么办?不幸的是,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

答案 1 :(得分:0)

您可以做的是设置进程的超时,一旦达到超时,您就可以使用以下命令终止进程:

n.terminate()

您也可以使用

.is_alive() 

检查进程或线程是否处于活动状态,如果已经达到超时,则终止它。

答案 2 :(得分:0)

您必须检查等待结果以确定返回的原因。如果它返回None,则由于其他原因返回等待,而不是子进程已终止。如果它返回None以外的其他内容,那么kill这个过程就不合适了,但这并不意味着如果它返回kill它自动适合None None }}。

例如,根据操作系统,None的返回可能表示您不希望将其终止的进程的状态更改。但也有可能会返回kill但仍在运行的情况可能会在您到达kill之前终止。

因此,如果您选择try进程,则应将其括在catch - timeout语句中,以便处理子进程已终止的场景。

同样来自python3.3,您可以添加n.wait(timeout=seconds_to_wait)(例如for package in server.packages: n = subprocess.Popen(['which', package], stdout=subprocess.DEVNULL) rc = n.wait() # in python3 you could supply timeout argument if rc != None: try: n.kill() except ProcessLookupError: pass code_to_run_when_killed() elif rc != 0: code_to_run_when_failed() # or perhaps you should raise exception else: code_to_run_when_exited_successfully() 参数等待,以便无限期等待。

您的代码可能如下所示:

<Image Source="/Resources/Phonebook36.jpg" />