有很多类似的问题和答案,但我仍然无法找到可靠的答案。
所以,我有一个功能,可能会运行太长时间。函数是私有的,在某种意义上我无法更改代码。
我想将执行时间限制为60秒。 我尝试了以下方法:
TimeoutException
之后仍然存在。multiprocessing
python模块。我有酸洗问题,我不知道如何解决它们。我想制作time_limit装饰器,并且在顶级导入所需的功能时出现问题。长时间执行的函数是实例方法,包装它也没有帮助...... 那么,上述问题是否有很好的解决方案?
如何杀死线程,我开始了吗?
如何使用子过程并避免酸洗问题?
subprocess
模块是否有任何帮助?
谢谢。
答案 0 :(得分:2)
我认为多处理方法是您唯一真正的选择。你纠正了线程不能被杀死(很好)并且信号有跨平台问题。这是一个多处理实现:
import multiprocessing
import Queue
def timed_function(return_queue):
do_other_stuff()
return_queue.put(True)
return
def main():
return_queue = multiprocessing.Manager().Queue()
proc = multiprocessing.Process(target=timed_function, args=(return_queue,))
proc.start()
try:
# wait for 60 seconds for the function to return a value
return_queue.get(timeout=60)
except Queue.Empty:
# timeout expired
proc.terminate() # kill the subprocess
# other cleanup
我知道你说你有酸洗问题,但几乎总能通过重构来解决。例如,您说您的long函数是一个实例方法。 可以包装这些类型的函数,以便在多处理中使用它们:
class TestClass(object):
def timed_method(self, return_queue):
do_other_stuff()
return_queue.put(True)
return
要在工作池中使用该方法,请将此包装器添加到模块的顶层:
def _timed_method_wrapper(TestClass_object, return_queue):
return TestClass_object(return_queue)
现在,您可以从同一类的不同方法对此类方法使用apply_async
:
def run_timed_method():
return_queue = multiprocessing.Manager().Queue()
pool = multiprocessing.Pool()
result = pool.apply_async(_timed_method_wrapper, args=(self, return_queue))
我非常确定只有在您使用multiprocessing.Pool而不是使用multiprocessing.Process对象启动子进程时才需要这些包装器。此外,我敢打赌,很多人会对这个结构感到不满,因为你正在打破类所提供的漂亮,干净的抽象,并且还会在类和其他随机包装函数之间创建依赖关系。你必须要决定是否让你的代码更难看是值得的。
答案 1 :(得分:-2)