22 python select subprocess timeout popen
我使用以下命令运行子进程:
p = subprocess.Popen("subprocess",
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)
此子进程可以立即退出stderr上的错误,也可以继续运行.我想检测这些条件中的任何一个 - 后者等待几秒钟.
我试过这个:
SECONDS_TO_WAIT = 10
select.select([],
[p.stdout, p.stderr],
[p.stdout, p.stderr],
SECONDS_TO_WAIT)
Run Code Online (Sandbox Code Playgroud)
但它只是返回:
([],[],[])
Run Code Online (Sandbox Code Playgroud)
无论哪种条件.我能做什么?
gri*_*eve 15
您是否尝试过使用Popen.Poll()方法.你可以这样做:
p = subprocess.Popen("subprocess",
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
time.sleep(SECONDS_TO_WAIT)
retcode = p.poll()
if retcode is not None:
# process has terminated
Run Code Online (Sandbox Code Playgroud)
这将使您始终等待10秒,但如果失败案例很少,则会在所有成功案例中摊销.
编辑:
怎么样:
t_nought = time.time()
seconds_passed = 0
while(p.poll() is not None and seconds_passed < 10):
seconds_passed = time.time() - t_nought
if seconds_passed >= 10:
#TIMED OUT
Run Code Online (Sandbox Code Playgroud)
这是一个忙碌的等待的丑陋,但我认为它完成了你想要的.
另外再看一下select call文档,我想你可能想要改变它如下:
SECONDS_TO_WAIT = 10
select.select([p.stderr],
[],
[p.stdout, p.stderr],
SECONDS_TO_WAIT)
Run Code Online (Sandbox Code Playgroud)
由于您通常希望从stderr读取,因此您想知道何时可以读取(即故障情况).
我希望这有帮助.
小智 8
这就是我提出的.在需要时工作,不需要在进程上超时,但是使用半忙循环.
def runCmd(cmd, timeout=None):
'''
Will execute a command, read the output and return it back.
@param cmd: command to execute
@param timeout: process timeout in seconds
@return: a tuple of three: first stdout, then stderr, then exit code
@raise OSError: on missing command or if a timeout was reached
'''
ph_out = None # process output
ph_err = None # stderr
ph_ret = None # return code
p = subprocess.Popen(cmd, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# if timeout is not set wait for process to complete
if not timeout:
ph_ret = p.wait()
else:
fin_time = time.time() + timeout
while p.poll() == None and fin_time > time.time():
time.sleep(1)
# if timeout reached, raise an exception
if fin_time < time.time():
# starting 2.6 subprocess has a kill() method which is preferable
# p.kill()
os.kill(p.pid, signal.SIGKILL)
raise OSError("Process timeout has been reached")
ph_ret = p.returncode
ph_out, ph_err = p.communicate()
return (ph_out, ph_err, ph_ret)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
44163 次 |
| 最近记录: |