超时时终止或终止子进程?

use*_*909 17 python subprocess signals timeout kill

我想尽快重复执行一个子进程.但是,有时这个过程需要很长时间,所以我想杀掉它.我使用signal.signal(...)如下所示:

ppid=pipeexe.pid
signal.signal(signal.SIGALRM, stop_handler)

signal.alarm(1)
.....
def stop_handler(signal, frame):
    print 'Stop test'+testdir+'for time out'
    if(pipeexe.poll()==None and hasattr(signal, "SIGKILL")):
         os.kill(ppid, signal.SIGKILL)
         return False
Run Code Online (Sandbox Code Playgroud)

但有时这段代码会试图阻止下一轮执行.停止测试/ home/lu/workspace/152/treefit/test2for time out/bin/sh:/ home/lu/workspace/153/squib_driver:not found ---这是下一次执行; 该程序错误地阻止它.

有谁知道如何解决这个问题?我想及时停止不执行1秒钟.sleep(n)经常等待n秒.我不希望我希望它可以执行不到1秒

ral*_*nja 41

你可以这样做:

import subprocess as sub
import threading

class RunCmd(threading.Thread):
    def __init__(self, cmd, timeout):
        threading.Thread.__init__(self)
        self.cmd = cmd
        self.timeout = timeout

    def run(self):
        self.p = sub.Popen(self.cmd)
        self.p.wait()

    def Run(self):
        self.start()
        self.join(self.timeout)

        if self.is_alive():
            self.p.terminate()      #use self.p.kill() if process needs a kill -9
            self.join()

RunCmd(["./someProg", "arg1"], 60).Run()
Run Code Online (Sandbox Code Playgroud)

我们的想法是创建一个运行该命令的线程,并在超时超过某个合适的值时将其终止,在这种情况下为60秒.

  • 还+1.这似乎是迄今为止我见过的最干净的方法之一.使用os.kill(self.p.pid,signal.SIGKILL)(或SIGTERM后跟SIGKILL)对Linux上的Python <2.6进行微小修改.也可以用self.out,self.err = self.p.communicate()替换self.p.wait(),以避免在填充stdout/stderr管道时阻塞子进程 (5认同)