我可以让用户在中间暂停正在运行的python脚本(在Windows下),并在用户决定时再次恢复吗?
有一个主管理器程序生成,加载和运行其他python脚本(通过从控制台调用python script.py)。我没有GUI,用户可以通过console进行交互。我希望我的主程序能够响应运行脚本的用户暂停/恢复命令。我应该定义一个线程吗?方法是什么?
编辑/更新:
假设我有一个带有前端的小型python应用程序,它具有各种功能。我有一个RUN命令在后台运行python脚本。我想实现一个暂停正在运行的python脚本的PAUSE功能。当用户再次命令RUN时,python脚本应该恢复 跑步。 使用raw_input()或print()强制用户发出命令。但在这种情况下,我们不知道用户何时想要中断/暂停/发出命令。因此通常的输入/打印不可用。
答案 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
模块。
尽管它是一个调试器,但对于您而言,它可以帮助您在代码中有断点的任何地方通过并继续。
另外,当您恢复时,您可以了解一下暂停的位置以及变量的值等,这将非常有帮助。