Как "остановить" и "возобновить" длительный запуск скрипта Python?

Я написал скрипт на Python, который обрабатывает большое количество больших текстовых файлов и может работать много времени. Иногда возникает необходимость остановить запущенный скрипт и возобновить его позже. Возможные причины для остановки скрипта: сбой программы, ситуация с диском "не хватает места" или многие другие, когда вам нужно это сделать. Я хочу реализовать своего рода механизм "остановки / возобновления" для сценария.

  • При остановке: скрипт завершает работу и сохраняет свое текущее состояние.
  • При возобновлении: сценарий запускается, но продолжается с последнего сохраненного состояния

Я собираюсь реализовать это, используя рассол и сигнальные модули.

Я буду рад услышать, как это сделать по-питонски.

Спасибо!

3 ответа

Решение

Вот кое-что простое, что, надеюсь, может помочь вам:

import time
import pickle


REGISTRY = None


def main(start=0):
    """Do some heavy work ..."""

    global REGISTRY

    a = start
    while 1:
        time.sleep(1)
        a += 1
        print a
        REGISTRY = pickle.dumps(a)


if __name__ == '__main__':
    print "To stop the script execution type CTRL-C"
    while 1:
       start = pickle.loads(REGISTRY) if REGISTRY else 0
        try:
            main(start=start)
        except KeyboardInterrupt:
            resume = raw_input('If you want to continue type the letter c:')
            if resume != 'c':
                break

Пример бега:

$ python test.py
To stop the script execution type CTRL-C
1
2
3
^CIf you want to continue type the letter c:c
4
5
6
7
8
9
^CIf you want to continue type the letter c:
$ python test.py

Если вы хотите читать большие файлы, просто используйте дескриптор файла и читайте строки по одной за раз, обрабатывая каждую строку по мере необходимости. Если вы хотите сохранить сеанс Python, просто используйте dill.dump_session - и это сохранит все существующие объекты. Другие ответы потерпят неудачу как pickle не могу выбрать дескриптор файла. dillтем не менее, может сериализовать почти каждый объект Python - включая дескриптор файла.

Python 2.7.9 (default, Dec 11 2014, 01:21:43) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> f = open('bigfile1.dat', 'r')
>>> data = f.readline()  
>>> 
>>> dill.dump_session('session.pkl')
>>> 

Затем выйдите из сеанса Python и перезапустите. Когда ты load_session, вы загружаете все объекты, которые существовали на момент dump_session вызов.

dude@hilbert>$ python
Python 2.7.9 (default, Dec 11 2014, 01:21:43) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> dill.load_session('session.pkl')
>>> len(data)
9
>>> data += f.readline()
>>> f.close()
>>> 

Просто как тот.

Получить dill здесь: https://github.com/uqfoundation

Выполнение может приостановить его жизнь или (кроме исключений безопасности), состояние сценария может быть pickled, застегнутый, и сохраненный

http://docs.python.org/library/pickle.html

http://docs.python.org/library/marshal.html

http://docs.python.org/library/stdtypes.html (5.9)

http://docs.python.org/library/archiving.html

http://www.henrysmac.org/?p=531

Другие вопросы по тегам