【问题标题】:User input to break infinite loop?用户输入打破无限循环?
【发布时间】:2017-02-19 18:35:01
【问题描述】:

我正在为一位数论家朋友计算一堆具有特殊属性的三角形。这些三角形有无数个,但它们需要大量的计算能力才能找到。

我们有一个无限循环通过不同的 b,d 组合运行。当程序结束时,它调用 go(dict) 函数来导出它找到的三角形。目前,我们在开始时告诉程序运行的时间间隔。当我们意识到我们需要计算能力来做其他事情时,这会导致问题,但是程序还有几个小时要运行,我们不想在不运行 go(dict) 的情况下退出程序而丢失它已经计算出的三角形。

理想情况下,我们希望一些用户输入导致程序中断循环,使用它在内存中保存的任何当前版本的字典运行 go(dict),然后退出。尝试使用 atexit.register(go, dict) 不成功,因为它在循环中被多次调用,并在程序终止时运行多次。

(参见下面的缩写循环代码)

interval = eval(input("How many hours shall I run for? "))*3600
starttime = time.time()
dict = {}
b = start_value
while True:
    for d in range (1, b):
        compute stuff

        if (condition):
            add triangle to dict

    if (time.time()-starttime)>interval:
        go(dict)
        return
    b +=1

【问题讨论】:

  • 你使用的是什么操作系统?

标签: python loops dictionary


【解决方案1】:

这是 are 可以用于的异常:您按 Ctrl+C 中断进程,您的代码通过保存结果来处理它:

while True:
    try:
        # your code here
    except KeyboardInterrupt:
        go(dict)
        break

请注意,您不能从独立循环中return,但是您可以从它中break

【讨论】:

  • 感谢您简洁明了的回答。您对中断的看法是正确的,但是我们正在特殊三角形中搜索独角兽,因此返回的是保存循环的函数(基本上放弃了搜索),因为循环后面的代码只能是找到我们要搜索的独角兽三角形后执行。
【解决方案2】:

您可以做的一件事是使用except KeyboardInterrupt: 接管 ctrl+c,当您向脚本发送中断时,它将运行此块,您可以在其中放置代码以干净地退出 这是一个例子:

i = 0
try:
    while True:
        i+=1
except KeyboardInterrupt:
    print 'caught INT'
    print i

【讨论】:

    【解决方案3】:

    使用信号:

    import signal
    interrupted = False # Used to break the loop when we send SIGINT
    
    # When SIGINT is received, set interrupted to True
    def signal_handler(signal, frame):
        global interrupted
        interrupted = True
    
    # Sets signal_handler to run if a SIGINT was received
    signal.signal(signal.SIGINT, signal_handler)
    
    interval = eval(input("How many hours shall I run for? "))*3600
    starttime = time.time()
    dict = {}
    b = start_value
    while True:
        for d in range (1, b):
            compute stuff
    
            if (condition):
                add triangle to dict
    
            if (time.time()-starttime)>interval:
                go(dict)
                break
    
            if interrupted:
                go(dict)
                break
        b +=1
    

    现在当我们点击ctrl+c 时,我们将interrupted 设置为True,它运行go(dict) 并中断循环。

    【讨论】:

    • 对以后来这里的人的好参考!
    猜你喜欢
    • 2018-10-17
    • 1970-01-01
    • 2013-03-08
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多