如何“停止”和“恢复”长时间运行的Python脚本?
我写了一个Python脚本,用来处理很多大的文本文件,这个脚本可能会运行很长时间。有时候,我需要停止这个正在运行的脚本,然后再继续。停止脚本的原因可能有很多,比如程序崩溃、磁盘空间不足等等。在这种情况下,我想为这个脚本实现一个“停止/恢复”的机制。
- 在停止时:脚本会退出并保存当前的状态。
- 在恢复时:脚本会启动,但会从最后保存的状态继续运行。
我打算使用pickle和signal模块来实现这个功能。
我很想知道如何用更Pythonic的方式来做到这一点。
谢谢!
3 个回答
0
程序的执行可以选择“睡觉”,也就是暂停运行,或者(除了安全方面的例外)可以把脚本的状态进行“腌制”(也就是保存),压缩,然后存储起来。
http://docs.python.org/library/pickle.html
http://docs.python.org/library/marshal.html
http://docs.python.org/library/stdtypes.html (5.9)
1
如果你想读取大文件,可以用文件句柄,一次读取一行,根据需要处理每一行。如果你想保存当前的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
4
这里有一些简单的内容,希望能对你有所帮助:
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