使用pid轮询子进程

时间:2016-06-29 08:57:56

标签: python django subprocess

我有一个django项目,允许用户一次启动多个子进程。这些过程可能需要一些时间,因此用户可以继续使用应用程序的其他方面。在任何情况下,用户都可以查看所有正在运行的进程并轮询它们中的任何一个以检查它是否结束。为此,我需要使用其pid轮询该进程。 Popen.poll()需要一个subprocess.Peopen对象,而我所拥有的只是该对象的pid。我怎样才能得到理想的结果?

在models.py中:

class Runningprocess(models.Model):
    #some other fields
    p_id=models.CharField(max_length=500)
    def __str__(self):
        return self.field1

在views.py中:

def run_process():
    ....
    p= subprocess.Popen(cmd, shell =True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    new_p=Runningprocess()  
    new_p.p_id=p.pid
    ....
    new_p.save()
    return HttpResponseRedirect('/home/')   

def check(request,pid):
    #here i want to be able to poll the subprocess using the p_id e.g something like:
     checkp = pid.poll() #this statement is wrong
     if checkp is None:
           do something
     else:
           do something else

我只需要一个有效的声明而不是'checkp = pid.poll()'

1 个答案:

答案 0 :(得分:1)

不使用PID进行轮询

PID是分配给进程的临时ID。只要进程正在运行,它就会与进程保持一致。当进程终止或被终止时,其PID可能(或可能不会立即)被分配给某个其他进程。因此,现在有效的进程的PID可能在某段时间后仍然无效。

现在,如何轮询某个流程?

这就是我在我的一个项目中所做的:

psub = subprocess.Popen(something)
# polling

while psub.poll() is None:
    pass

但请注意,上述代码可能会导致死锁。为避免死锁,您可以使用两种方法:

  1. 使用计数器。当计数器值大于某个固定值时 - 终止该过程。
  2. 2.使用超时。获取进程启动时的开始时间以及进程花费的时间超过固定时间 - kill。

    start_time = time.time()
    timeout = 60 # 60 seconds
    while psub.poll() is None:
        if time.time() - start_tym >= int(timeout):
            psub.kill()