我有一个可能会陷入长时间循环的代码。这些不是无限循环,但是某些输入可能会导致循环持续较长时间。我希望在循环太长的情况下使用中断。使用此中断,循环将重新评估其输入,因此键盘中断不是我想要的。我在Windows上使用的是python 2.7。
一种可能的方法是使用time.time()进行轮询,但是效率极低。循环本身并不长,但是即使在正常运行中,它也要迭代10万次,因此每次迭代后我都无法轮询时间,这会大大降低效率。另外,我可以介绍更多变量,
i=0
while i<some_very_large_number:
function(foo, foo1, foo2)
i=i+1
但这还是一个中等的解决方案。
简而言之,我正在寻找的是等同于微处理器硬件中断的python。我没有多线程经验,因此,如果答案在于多线程,请详细说明。
我已经检查了here和here,但我认为他们没有回答我的问题。第二个链接实际上可以提供帮助,但显然Windows中没有可用的软件包。
代码很长,但是很简单。它基本上具有这样的结构。
def function(foo, foo1, foo2, N):
for i in range(N):
performance = performance_evaluator(foo, foo1, foo2)
if performance_takes_too_long:
interrupt ##this if clause is the main objective of this question##
record performance
new_foo, new_foo1, new_foo2 = evolve(foo, foo1, foo2)
答案 0 :(得分:1)
一种可行的方法是修改脚本,使其通过命令行参数获取输入,然后使用subprocess
模块以超时运行它:
# manager.py
import subprocess
try:
code = subprocess.call('python work.py 5', timeout=2)
print('Ended with code:', code)
except subprocess.TimeoutExpired:
print('Ended with timeout')
# work.py
import sys
from time import sleep
try:
wait = int(sys.argv[1])
except:
wait = 10
sleep(wait)
print(f'Waited for {wait} seconds')
输出:
Ended with timeout
答案 1 :(得分:1)
您还可以在单独的工作进程中执行长时间运行的代码,并在超过超时且工作程序尚未完成时尝试终止它:
import time
from multiprocessing import Process
def process_data():
while True:
print("processing...")
time.sleep(1)
def main():
worker = Process(target=process_data)
worker.start()
timeout = 5
time.sleep(timeout)
if worker.is_alive():
print("exceeded timeout", timeout, "sec")
print("terminate worker", worker)
worker.terminate()
worker.join()
print("is worker", worker, "alive:", worker.is_alive())
if __name__ == "__main__":
main()
以下是输出:
processing...
processing...
processing...
processing...
processing...
exceeded timeout 5 sec
terminate worker <Process(Process-1, started)>
is worker <Process(Process-1, stopped[SIGTERM])> alive: False