我有一个执行一些exes的IronPython脚本。如果当前的exe超过一定的时间,我想停止执行当前的exe。我怎么能这样做?
当前功能:
def execute(programName):
t0 = time.time()
#should stop the execution of "programName"
#if execution exceeds limit
p = os.popen(programName,"r")
result = p.readline()
p.close()
execTime = time.time() - t0
return result, execTime
答案 0 :(得分:1)
这段代码适用于我使用python。我不确定它在IronPython上的表现如何,希望无论如何都会有所帮助。
"""
Monitors a set of processes execution, and termination
"""
import subprocess
from threading import Thread
import time
class ProcessMonitor( Thread ):
def __init__(self):
Thread.__init__(self)
self.processList = {}
self.running = True
def monitor( self, pClass, timeout ):
self.processList[ pClass ] = (time.time(),0,timeout)
def stop(self):
running = false
def run(self):
print time.time() # just for debugging!!
while self.running:
# sleep for a second
time.sleep(10)
# go over all processes and update the time
for pClass in self.processList:
currentTime = time.time()
# if the process didn't terminate yet
if pClass.poll() == None:
# check if needs to be terminated!
(time_,overall,timeout)=self.processList[pClass]
overall = overall + (currentTime-time_)
print "%f seconds passed from running of process %d"%(overall,pClass.pid)
if overall > timeout:
pClass.kill()
del self.processList[ pClass]
else:
self.processList[pClass] = (currentTime,overall,timeout)
else:
del self.processList[ pClass ]
答案 1 :(得分:1)
由于它在IronPython中,我认为它在Windows上运行,因此进程管理可能与我从unix中所知的不同。
从您的代码来看,您要做的是:“读取流程的标准输出,如果运行时间过长就将其删除”。要正确执行此操作,您需要标准输出上的非阻塞读取,读取进程输出的临时文件或两个执行线程。
一个线程将读取子进程输出。
另一个线程将定期轮询进程以检查它是否终止,如果它在一段时间后没有终止,则将其终止。如果你不想轮询,你需要一个额外的线程:一个到子进程的wait()
,另一个在一段时间后杀掉它。
相关标准库模块:
popen
,在各方面都更好。答案 2 :(得分:1)
如果您不需要与CPython兼容的代码(听起来不像那样),您可以使用.NET facilities进行流程管理,例如System.Diagnostics.Process
类。它可能比使用os.popen
更简单。
答案 3 :(得分:1)
这是我如何做的...它确实使用了子进程,所以你需要调整它以使用popen。
class KillerThread(threading.Thread):
def __init__(self, pid, timeout, event ):
threading.Thread.__init__(self)
self.pid = pid
self.timeout = timeout
self.event = event
self.setDaemon(True)
def run(self):
self.event.wait(self.timeout)
if not self.event.isSet() :
try:
os.kill( self.pid, signal.SIGKILL )
except OSError, e:
#This is raised if the process has already completed
pass
def runTimed(dt, args, kwargs ):
event = threading.Event()
proc = subprocess.Popen(args, **kwargs )
killer = KillerThread(proc.pid, dt, event)
killer.start()
(stdout, stderr) = proc.communicate()
event.set()
return (stdout,stderr, proc.returncode)
#EXAMPLE USAGE - lets it run for at most 3 seconds
(stdout, stderr, returncode) = \
runTimed(3, \
["path/to/my/executable", "arg1" ] , \
{'stdout':subprocess.PIPE, 'stderr':subprocess.PIPE} )
如果使用stderr,stdout,则可以避免需要额外的线程 直接而不是使用通信,您只需要小心在这些句柄上使用非阻塞IO。
答案 4 :(得分:0)
我认为您可以在子进程模块中使用Popen.poll来执行您想要的操作。 (os.popen在2.6中弃用)