2024-10-04 09:26:55 发布
网友
sigalm依赖于使用中断设置的警报-- Using module 'subprocess' with timeout
问题是我有多个Python脚本使用信号报警进程设置超时,并且只调用最新的警报。有什么好方法可以改进设置超时的多个Python函数?在
除了简单、快速的黑客攻击,避免使用sigalm。这是一种非常古老、有限的机制,不适合更复杂的情况:您只能设置一个警报,它会中断任何系统调用,而不仅仅是您要中断的系统调用。在
使用超时线程终止进程会更干净,例如:
import subprocess, signal, os, threading, errno from contextlib import contextmanager class TimeoutThread(object): def __init__(self, seconds): self.seconds = seconds self.cond = threading.Condition() self.cancelled = False self.thread = threading.Thread(target=self._wait) def run(self): """Begin the timeout.""" self.thread.start() def _wait(self): with self.cond: self.cond.wait(self.seconds) if not self.cancelled: self.timed_out() def cancel(self): """Cancel the timeout, if it hasn't yet occured.""" with self.cond: self.cancelled = True self.cond.notify() self.thread.join() def timed_out(self): """The timeout has expired.""" raise NotImplementedError class KillProcessThread(TimeoutThread): def __init__(self, seconds, pid): super(KillProcessThread, self).__init__(seconds) self.pid = pid def timed_out(self): try: os.kill(self.pid, signal.SIGKILL) except OSError as e: # If the process is already gone, ignore the error. if e.errno not in (errno.EPERM, errno. ESRCH): raise e @contextmanager def processTimeout(seconds, pid): timeout = KillProcessThread(seconds, pid) timeout.run() try: yield finally: timeout.cancel() def example(): proc = subprocess.Popen(["sleep", "5"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) with processTimeout(1, proc.pid): print proc.communicate() resultcode = proc.wait() if resultcode < 0: print "error: %i" % resultcode if __name__ == '__main__': example()
根据您的超时情况,您可能需要使用比SIGKILL更轻的信号,以允许超时进程自行清理。在
除了简单、快速的黑客攻击,避免使用sigalm。这是一种非常古老、有限的机制,不适合更复杂的情况:您只能设置一个警报,它会中断任何系统调用,而不仅仅是您要中断的系统调用。在
使用超时线程终止进程会更干净,例如:
根据您的超时情况,您可能需要使用比SIGKILL更轻的信号,以允许超时进程自行清理。在
相关问题 更多 >
编程相关推荐