天天看點

python os popen_python 解決os.popen 逾時問題

Python 使用函數 os.popen 會出現過長時間等待導緻阻塞問題。

python os popen_python 解決os.popen 逾時問題

解決方法如下:

def TIMEOUT_COMMAND(command, timeout):

"""call shell-command and either return its output or kill it

if it doesn't normally exit within timeout seconds and return None"""

import subprocess, datetime, os, time, signal

cmd = command.split(" ")

start = datetime.datetime.now()

process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

while process.poll() is None:

time.sleep(0.2)

now = datetime.datetime.now()

if (now - start).seconds> timeout:

os.kill(process.pid, signal.SIGKILL)

os.waitpid(-1, os.WNOHANG)

return None

return process.stdout.readlines()

循環

忙等 子程序結束

import subprocess

import os

import time

tt = '555'

cmd = "python /home/100003/python/mypython/sub2.py "+" 333"+" 444 "+tt

print time.time()

sub2 = subprocess.Popen(cmd, shell=True)

while 1:

ret1 = subprocess.Popen.poll(sub2)

if ret1 == 0:

print sub2.pid,'end'

break

elif ret1 is None:

print 'running'

time.sleep(1)

else:

print sub2.pid,'term'

break

print time.time()

子程序結束

立即傳回 使用select子產品 同時可設定子程序的逾時時間

import subprocess

import select

import time

import signal

import os

tt = '555'

cmd = "python /home/100003/python/mypython/sub2.py "+" 333"+" 444 "+tt

timeout = 3

pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,shell = True)

print time.time()

while 1:

while_begin = time.time()

print 'timeout',timeout

fs = select.select([pro.stdout], [], [], timeout)

if pro.stdout in fs[0]:

tmp = pro.stdout.read()

print 'read', tmp

if not tmp:

print 'end'

print time.time()

break

else:

print 'outoftime'

print os.kill(pro.pid, signal.SIGKILL),

break

timeout = timeout - (time.time() - while_begin)

import subprocess, threading

class Command(object):

def __init__(self, cmd):

self.cmd = cmd

self.process = None

def run(self, timeout):

def target():

print 'Thread started'

self.process = subprocess.Popen(self.cmd, shell=True)

self.process.communicate()

print 'Thread finished'

thread = threading.Thread(target=target)

thread.start()

thread.join(timeout)

if thread.is_alive():

print 'Terminating process'

self.process.terminate()

thread.join()

print self.process.returncode

command = Command("echo 'Process started'; sleep 2; echo 'Process finished'")

command.run(timeout=3)

command.run(timeout=1)

Thread started

Process started

Process finished

Thread finished

Thread started

Process started

Terminating process

Thread finished

-15

如果數unix 系統

import signal

proc = subprocess.Popen(

cmd,

stderr=subprocess.STDOUT, # merge stdout and stderr

stdout=subprocess.PIPE,

shell=True)

...

class Alarm(Exception):

pass

def alarm_handler(signum, frame):

raise Alarm

signal.signal(signal.SIGALRM, alarm_handler)

signal.alarm(5*60) # 5 minutes

try:

stdoutdata, stderrdata = proc.communicate()

signal.alarm(0) # reset the alarm

except Alarm:

print "Oops, taking too long!"

# whatever else