等待某个进程(知道pid)结束

时间:2022-12-04 19:23:57

I have this:

我有这个:

def get_process():
    pids = []
    process = None
    for i in os.listdir('/proc'):
        if i.isdigit():
            pids.append(i)

    for pid in pids:
        proc = open(os.path.join('/proc', pid, 'cmdline'), 'r').readline()
        if proc == "Something":
            process = pid

    return process          

def is_running(pid):
    return os.path.exists("/proc/%s" % str(pid))

Then i do this:

然后我这样做:

process = get_process()
if process == None:
    #do something
else:
    #Wait until the process end
    while is_running(process):
        pass

I think this is not the best way to wait for the process to terminate, there must be some function wait or something, but i can't find it.

我认为这不是等待进程终止的最好方式,一定有一些函数等待之类的,但是我找不到。

Disclaimer: The process is not a child process

免责声明:该过程不是子过程

3 个解决方案

#1


9  

I'm not really a Python programmer, but apparently Python does have os.waitpid(). That should consume less CPU time and provide a much faster response than, say, trying to kill the process at quarter-second intervals.

我并不是真正的Python程序员,但是显然Python有os.waitpid()。这将消耗更少的CPU时间,并提供比试图每隔四分之一秒终止进程更快的响应。


Addendum: As Niko points out, os.waitpid() may not work if the process is not a child of the current process. In that case, using os.kill(pid, 0) may indeed be the best solution. Note that, in general, there are three likely outcomes of calling os.kill() on a process:

附录:正如Niko指出的,如果进程不是当前进程的子进程,那么os.waitpid()可能无法工作。在这种情况下,使用os。kill(pid, 0)可能确实是最好的解决方案。注意,一般来说,在一个过程中调用os.kill()有三种可能的结果:

  1. If the process exists and belongs to you, the call succeeds.
  2. 如果该进程存在并属于您,则调用成功。
  3. If the process exists but belong to another user, it throws an OSError with the errno attribute set to errno.EPERM.
  4. 如果进程存在,但属于另一个用户,它将抛出一个OSError,并将errno属性设置为errno eperm。
  5. If the process does not exist, it throws an OSError with the errno attribute set to errno.ESRCH.
  6. 如果进程不存在,则抛出一个OSError,并将errno属性设置为errno. esrch。

Thus, to reliably check whether a process exists, you should do something like

因此,要可靠地检查流程是否存在,您应该执行以下操作

def is_running(pid):        
    try:
        os.kill(pid, 0)
    except OSError as err:
        if err.errno == errno.ESRCH:
            return False
    return True

#2


1  

import time, then use time.sleep(#):

导入时间,然后使用时间。sleep(#):

import time
process = get_process()
if process == None:
    #do something
else:
    #Wait until the process end
    while is_running(process):
        time.sleep(0.25)

I also have that exact same function in several of my scrips to read through /proc/#/cmdline to check for a PID.

我在我的几个脚本中也有相同的函数来读取/proc/#/cmdline以检查PID。

#3


1  

Since that method would only work on linux, for linux/osx support, you could do:

由于该方法只适用于linux,对于linux/osx支持,您可以这样做:

import time
import os

def is_running(pid):
    stat = os.system("ps -p %s &> /dev/null" % pid)
    return stat == 0

pid = 64463

while is_running(pid):
    time.sleep(.25)

Edit - Per tMc's comment about excessive processes

编辑- tMc关于过度进程的评论

Referencing: How to check if there exists a process with a given pid in Python?

引用:如何检查Python中是否存在具有给定pid的进程?

Wouldn't this use less resources (I havent tested), than listing on the filesystem and opening FDs to all the results?

这难道不会比在文件系统中列出并打开FDs以获取所有结果更少的资源(我还没有测试)吗?

import time
import os

def is_running(pid):        
    try:
        os.kill(pid, 0)
    except OSError:
        return False

    return True

pid = 64463

while is_running(pid):
    time.sleep(.25)

#1


9  

I'm not really a Python programmer, but apparently Python does have os.waitpid(). That should consume less CPU time and provide a much faster response than, say, trying to kill the process at quarter-second intervals.

我并不是真正的Python程序员,但是显然Python有os.waitpid()。这将消耗更少的CPU时间,并提供比试图每隔四分之一秒终止进程更快的响应。


Addendum: As Niko points out, os.waitpid() may not work if the process is not a child of the current process. In that case, using os.kill(pid, 0) may indeed be the best solution. Note that, in general, there are three likely outcomes of calling os.kill() on a process:

附录:正如Niko指出的,如果进程不是当前进程的子进程,那么os.waitpid()可能无法工作。在这种情况下,使用os。kill(pid, 0)可能确实是最好的解决方案。注意,一般来说,在一个过程中调用os.kill()有三种可能的结果:

  1. If the process exists and belongs to you, the call succeeds.
  2. 如果该进程存在并属于您,则调用成功。
  3. If the process exists but belong to another user, it throws an OSError with the errno attribute set to errno.EPERM.
  4. 如果进程存在,但属于另一个用户,它将抛出一个OSError,并将errno属性设置为errno eperm。
  5. If the process does not exist, it throws an OSError with the errno attribute set to errno.ESRCH.
  6. 如果进程不存在,则抛出一个OSError,并将errno属性设置为errno. esrch。

Thus, to reliably check whether a process exists, you should do something like

因此,要可靠地检查流程是否存在,您应该执行以下操作

def is_running(pid):        
    try:
        os.kill(pid, 0)
    except OSError as err:
        if err.errno == errno.ESRCH:
            return False
    return True

#2


1  

import time, then use time.sleep(#):

导入时间,然后使用时间。sleep(#):

import time
process = get_process()
if process == None:
    #do something
else:
    #Wait until the process end
    while is_running(process):
        time.sleep(0.25)

I also have that exact same function in several of my scrips to read through /proc/#/cmdline to check for a PID.

我在我的几个脚本中也有相同的函数来读取/proc/#/cmdline以检查PID。

#3


1  

Since that method would only work on linux, for linux/osx support, you could do:

由于该方法只适用于linux,对于linux/osx支持,您可以这样做:

import time
import os

def is_running(pid):
    stat = os.system("ps -p %s &> /dev/null" % pid)
    return stat == 0

pid = 64463

while is_running(pid):
    time.sleep(.25)

Edit - Per tMc's comment about excessive processes

编辑- tMc关于过度进程的评论

Referencing: How to check if there exists a process with a given pid in Python?

引用:如何检查Python中是否存在具有给定pid的进程?

Wouldn't this use less resources (I havent tested), than listing on the filesystem and opening FDs to all the results?

这难道不会比在文件系统中列出并打开FDs以获取所有结果更少的资源(我还没有测试)吗?

import time
import os

def is_running(pid):        
    try:
        os.kill(pid, 0)
    except OSError:
        return False

    return True

pid = 64463

while is_running(pid):
    time.sleep(.25)