在中间暂停/恢复python脚本



我可以有一个运行的python脚本(在Windows下)被暂停在中间由用户,并再次恢复当用户决定?

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

编辑/更新:

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

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

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。

您可以通过创建PAUSEFILE来做一个简单的解决方案。要暂停的脚本可能会定期检查这样的文件是否存在(或内容)。

用户的PAUSE命令可以创建(或填充适当的内容)这样的文件。

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

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

在主循环中。

它很讨厌,如果代码真的依赖于它,它可能会被破坏,但对于用例来说,暂停是由用户随机完成的,我想这无关紧要。

PAUSE命令是简单的touch $PAUSEFILE

好的,从我在搜索中看到的,即使有线程,sys.stdin也会对你不利,无论你如何得到它(input(),甚至sys.stdin.read())。readline()等),因为它们阻塞了。

相反,把你的管理器程序写成一个套接字服务器或类似的东西。

将脚本编写为生成器,旨在暂停执行(每次遇到yield时),并依次重复地调用每个脚本的next()。当脚本完成时,您将得到一个StopIteration异常。

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

服务器在脚本上运行下一次迭代之前拾取这些命令,如果脚本被用户暂停,则管理器程序在用户告诉它再次运行之前不会对该脚本调用next()

我还没有测试过这个,但我认为它会比为外部脚本创建线程或子进程,然后尝试暂停(稍后杀死)它们更好。


这真的超出了我的深度,但也许在后台运行脚本并使用kill -stopkill -cont暂停和继续将工作(假设Linux)?

我不太明白你的方法,但每次用户需要按回车键继续脚本时,你应该使用:

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

而不将接收到的答案赋值给变量。

我觉得这些回答很粗俗,但也很有趣。

最好的方法是https://stackoverflow.com/a/7184165/2480481使用KeyboardInterrupt异常。

因为我注意到没有人提到"使用调试器",所以我将这么做。

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

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

还可以添加带有pdb的Ipython接口,以便在应用程序崩溃时进行调试。查看:https://stackoverflow.com/a/14881323/2480481

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

您可以在python中使用Pdb模块。尽管它是一个调试器,但在您的情况下,它可以帮助您在代码中有断点的地方传递并继续。

同样,当你恢复时,你可以看到它暂停的位置和变量的值等。这将非常有帮助。

python debugger - pdb

我一直在寻找这个很长时间。因此我决定自己解决这个问题。下面的代码对我来说很好。

在开始循环之前,简单地为用户打印一条指令行。

这是我的代码-

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块(用户可以在其中提供恢复、保存当前输出或退出代码的输入)

对于resume功能,循环的当前位置被保存并反馈到start For循环中。

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

您尝试过明显的打印提示符然后从stdin读取一行吗?这将暂停整个脚本。

你在最初的问题中问的不是很清楚,所以如果这不是你想要的,你能解释为什么吗?

在Windows中,您可以暂停/恢复正在运行的Python脚本。在CMD或通过运行命令(Windows+R)键入resmon。找到Python脚本进程并右键单击>Suspend process。这将解锁CPU使用率,但不会解锁RAM。;)

在Linux终端:

sudo pkill -STOP python3
sudo pkill -CONT python3

如果你想在python中做,然后用文本

创建config.ini。
[control]
pausescript = False

然后在python脚本中:

from configparser import ConfigParser
config = ConfigParser()
config.read("config.ini")

和脚本中循环的地方:

  pauseScript = True
  while pauseScript:
    config.read("config.ini")
    pauseScript = config.getboolean('control', 'pausescript')
    if pauseScript:
      print("Script paused. Resume by change config setting to False.                                    ",end="r")
      time.sleep(0.3)

然后通过在config.ini文件

中设置True或False来控制脚本

最新更新