我无法理解何时需要杀死子进程。
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
当子进程自杀以及我需要手动执行时,有人可以解释一下吗?
答案 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" />