暂停/恢复中间的python脚本

时间:2011-08-24 19:07:26

标签: python

我可以让用户在中间暂停正在运行的python脚本(在Windows下),并在用户决定时再次恢复吗?

有一个主管理器程序生成,加载和运行其他python脚本(通过从控制台调用python script.py)。我没有GUI,用户可以通过console进行交互。我希望我的主程序能够响应运行脚本的用户暂停/恢复命令。我应该定义一个线程吗?方法是什么?

编辑/更新:

假设我有一个带有前端的小型python应用程序,它具有各种功能。我有一个RUN命令在后台运行python脚本。我想实现一个暂停正在运行的python脚本的PAUSE功能。当用户再次命令RUN时,python脚本应该恢复 跑步。 使用raw_input()或print()强制用户发出命令。但在这种情况下,我们不知道用户何时想要中断/暂停/发出命令。因此通常的输入/打印不可用。

10 个答案:

答案 0 :(得分:13)

如果它是unix我会推荐信号,但这是一个粗略的版本,可以满足您的要求。

import time

while True:
    try:
        time.sleep(1)  # do something here
        print '.',

    except KeyboardInterrupt:
        print '\nPausing...  (Hit ENTER to continue, type quit to exit.)'
        try:
            response = raw_input()
            if response == 'quit':
                break
            print 'Resuming...'
        except KeyboardInterrupt:
            print 'Resuming...'
            continue

使用Ctrl + C暂停,然后按ENTER继续。 Ctrl + Break可能会被用作严厉杀戮,但我没有这个键盘上的键。

更强大的版本可以在管道/套接字甚至线程上使用select。

答案 1 :(得分:8)

您可以通过创建PAUSEFILE来制定简单的解决方法。您的待暂停脚本可能会定期检查此类文件的存在(或内容)。

用户PAUSE命令可以创建(或填写适当的内容)此类文件。

我在类似的情况下使用过这种方法,我希望能够暂停我的Python脚本并在以后恢复它们。它们包含类似

的内容
if os.path.isfile(PAUSEFILE):
  raw_input('Remove ' + PAUSEFILE + ' and hit ENTER to continue')

在他们的主循环中。

如果代码真的依赖于它,它会很糟糕并且可能会被破坏,但对于用例,用户随机进行暂停,我想这无关紧要。

PAUSE命令只是touch $PAUSEFILE

答案 2 :(得分:5)

我不太了解您的方法,但每次用户需要按Enter键继续您应该使用的脚本时:

input() #for python 3k
raw_input() #for python 2k

没有将接收答案分配给变量。

答案 3 :(得分:4)

好的,从我在搜索中看到的情况来看,即使使用线程,sys.stdin也会对你产生影响,无论你如何处理它(input(),甚至{ {1}},。sys.stdin.read()等),因为它们会阻止。

相反,将您的经理程序编写为套接字服务器或类似的东西。

将脚本编写为生成器,用于暂停执行(每次访问readline()时),并依次在每个脚本上依次调用yield。脚本完成后,您将收到next()异常。

为了处理命令,编写第二个脚本连接到管理器程序的套接字并向其发送消息,这将是用户与之交互的控制台界面(稍后,您甚至可以将其升级到GUI而不会在其他地方进行更改)

服务器在脚本上运行下一次迭代之前选择这些命令,如果用户暂停了脚本,那么管理器程序就不会在该脚本上调用StopIteration,直到用户告诉它为止又跑了。

我没有对此进行过测试,但我认为它比为外部脚本创建线程或子进程更好,然后尝试暂停(以后再杀掉)它们。


这真的不是我的深度,但是可能在后台运行脚本并使用next()kill -stop暂停和继续可以工作(假设Linux)?

答案 4 :(得分:1)

我找了这么久。于是决定自己解决。 下面的代码对我来说很好用。

在开始循环之前,只需为用户打印一条指令行。

这是我的代码 -

import time
start = 0

run = True
while run == True:        
    try :
        # Loop Code Snippet
        for i in range(start,100):
            time.sleep(2)
            print(i)
            start = i+1
    except :
        print("""~~~~~~~Code interupted~~~~~~~ 
        \n Press 1 to resume 
        \n Press 2 to quit""")
        res = input()
        if res == "1" :
            print("1")
            # pass and resume code
            pass
        if res == "2" :
            print("2") 
            #Save output and quit code
            run = False
        pass  #Safety pass if case user press invalid input

可以使用常规的“Ctrl + C”方式中断这段代码。

这是如何工作的 - 当代码中断时,会引发“键盘中断”错误。由于哪个错误处理程序“Try:Except”将转到Except 块(用户可以在其中提供输入以恢复、保存当前输出或退出代码)

对于恢复功能,循环的当前位置被保存并作为开始循环反馈。

这里有很多改进点,期待建议。

答案 5 :(得分:0)

您是否尝试过显而易见的打印提示然后从标准输入读取一行?那会暂停你的整个剧本。

您在原始问题中提到的内容不是很清楚,所以如果这不符合您的要求,您能解释一下原因吗?

答案 6 :(得分:0)

如果您从Windows命令窗口启动python脚本,则可以使用msvcrt.kbhit()作为非阻塞按键检查,如下所示: http://code.activestate.com/recipes/197140-key-press-detection-for-windows-text-only-console-/

答案 7 :(得分:0)

我发现这些回答太过苛刻,同时也很有趣。

最好的方法是https://stackoverflow.com/a/7184165/2480481使用KeyboardInterrupt例外做法。

正如我注意到没有人提及"使用调试器",我会这样做。

使用pip install pdb安装pdb,Python调试器。 然后按Ctrl + c使脚本可以使用https://stackoverflow.com/a/39478157/2480481,而不是退出。

使用调试器(pdb)的主要好处是可以检查变量,值等。这远比暂停/继续它更强大。

此外,您可以添加带有pdb的Ipython接口,以便在崩溃时调试您的应用。请看:https://stackoverflow.com/a/14881323/2480481

答案 8 :(得分:0)

在Windows中,您可以暂停/继续运行Python脚本。在CMD上或通过运行命令(Windows + R)键入resmon。找到您的Python脚本进程,然后右键单击>“挂起进程”。这将解锁CPU使用率,但不会解锁RAM。 ;)

答案 9 :(得分:0)

您可以在python中使用Pdb模块。 尽管它是一个调试器,但对于您而言,它可以帮助您在代码中有断点的任何地方通过并继续。

另外,当您恢复时,您可以了解一下暂停的位置以及变量的值等,这将非常有帮助。

python debugger - pdb