#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)