如何“停止”和“恢复”长时间运行的Python脚本?

12 投票
3 回答
6720 浏览
提问于 2025-04-16 19:17

我写了一个Python脚本,用来处理很多大的文本文件,这个脚本可能会运行很长时间。有时候,我需要停止这个正在运行的脚本,然后再继续。停止脚本的原因可能有很多,比如程序崩溃、磁盘空间不足等等。在这种情况下,我想为这个脚本实现一个“停止/恢复”的机制。

  • 停止时:脚本会退出并保存当前的状态。
  • 恢复时:脚本会启动,但会从最后保存的状态继续运行。

我打算使用picklesignal模块来实现这个功能。

我很想知道如何用更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)

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

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

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

就是这么简单。

你可以在这里获取 dillhttps://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

撰写回答