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

#python #pickle

#python #pickle

Вопрос:

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

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

Я собираюсь реализовать это с помощью модулей pickle и signal.

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

Спасибо!

Комментарии:

1. Скорее всего, вам понадобится какой-то внешний элемент управления, например, запланированная задача (или задание cron в Linux). Кроме того, при остановке программы запишите некоторую информацию о состоянии в определенный файл на диске, чтобы ваша программа знала, что делать при перезапуске

2. В системах * nix вы можете использовать стандартные сигналы SIGSTOP и SIGCONT, хотя процесс будет оставаться в (виртуальной) памяти до тех пор, пока не будет продолжен.

Ответ №1:

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

 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
  

Комментарии:

1. Операционная система хочет обработать несколько текстовых файлов. Итак, в глобальных файлах должны быть дескрипторы. pickle не удается сериализовать дескрипторы файлов. Следовательно, ваш ответ не должен работать, в общем … и особенно для того, чего хочет OP.

Ответ №2:

Если вы хотите прочитать большие файлы, просто используйте дескриптор файла и читайте строки по одной за раз, обрабатывая каждую строку по мере необходимости. Если вы хотите сохранить сеанс 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

Ответ №3:

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

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