2017-02-19 28 views
2

Я работаю над вычислением множества треугольников со специальными свойствами для друга-теоретика числа. Существует бесконечно много этих треугольников, но они требуют много вычислительной силы для поиска.Пользовательский ввод для прерывания бесконечного цикла?

У нас есть бесконечный цикл, проходящий через различные комбинации 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 
+0

Какая операционная система вы используете? – martineau

ответ

4

Это то, что исключения являются могут быть использованы для: при нажатии Ctrl + C, чтобы прервать процесс, и ваш код обрабатывает его, сохранив результаты:

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

Обратите внимание, что вы не можете return из автономного цикла, но вы можете break от него, однако.

+0

Спасибо за четкий и краткий ответ. Вы правильно относитесь к разрыву, но мы ищем единорога среди специальных треугольников, поэтому возврат - это функция, которая удерживает цикл (по сути, отказ от поиска), так как есть код, который следует за циклом, только для выполненный, как только найден найденный треугольник единорога. –

1

одна вещи, которую вы можете сделать, это взять на Ctrl + C, используя except KeyboardInterrupt: при отправке прерывания скрипта он будет работать этот блок, в котором вы можете поместить код для выхода чисто вот пример:

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

Использование сигналов:

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) и разрывает петлю.

+1

Хорошая ссылка для людей, которые приходят сюда в будущем! –