简体   繁体   English

用户输入打破无限循环?

[英]User input to break infinite loop?

I'm working on calculating a bunch of triangles with special properties for a Number Theorist friend. 我正在为Number Theorist朋友计算一堆具有特殊属性的三角形。 There are infinitely many of these triangles, but they require a lot of computational power to find. 这些三角形有很多,但是要找到它们需要大量的计算能力。

We've got an infinite loop running through different b,d combinations. 我们有一个无限循环,通过不同的b,d组合运行。 When the program ends, it calls the go(dict) function to export the triangles it found. 程序结束时,它将调用go(dict)函数以导出找到的三角形。 Currently, we tell the program at the start what interval of time to run for. 目前,我们在开始时告诉程序要运行的时间间隔。 This is causing problems when we realize we need the computing power for something else, but the program still has hours to run and we don't want to lose the triangles it has already calculated by exiting the program without running go(dict). 当我们意识到我们需要计算能力来做其他事情时,这会引起问题,但是程序仍然要运行几个小时,并且我们不想通过不运行go(dict)退出程序而丢失已经计算出的三角形。

Ideally, we want some user input to cause the program to break the loop, run go(dict) with whatever current version of the dictionary it is holding in memory, then exit. 理想情况下,我们希望某些用户输入导致程序中断循环,使用其在内存中保留的当前词典版本运行go(dict),然后退出。 Trying with atexit.register(go, dict) was unsuccessful, as it is called many times within the loop and runs many times when the program is terminated. 尝试使用atexit.register(go,dict)不成功,因为它在循环中被多次调用,并在程序终止时运行多次。

(See the abbreviated loop code below) (请参见下面的缩写循环代码)

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

This is what exceptions are can be used for: you press Ctrl+C to interrupt the process, and your code handles it by saving the results: 这是可以用于异常 东西:您按Ctrl + C中断该过程,然后您的代码通过保存结果来处理它:

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

Note that you can't return from a standalone loop, but you can break from it, however. 请注意,您不能从独立循环中return ,但是可以break它。

one thing you can do is take over ctrl+c using except KeyboardInterrupt: when you send an interrupt to the script it will run this block in which you can put code to exit cleanly here is an example: 您可以做的一件事是使用except KeyboardInterrupt:来接管ctrl + c except KeyboardInterrupt:当您向脚本发送中断时,它将运行此代码块,您可以在其中放置干净的代码,下面是一个示例:

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

Using Signals: 使用信号:

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

Now when we hit ctrl+c , we set interrupted to True which runs go(dict) and breaks the loop. 现在,当我们按下ctrl+c ,我们将interrupted设置为True ,这会运行go(dict)并中断循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM