有效要求python停止(受控)的高效方法(从bash命令/tmp/stop?)

2024-04-25 08:18:33 发布

您现在位置:Python中文网/ 问答频道 /正文

请求Python程序从Bash脚本停止(以受控方式)的最有效方法是什么(就轮询开销而言)。在python方面,我需要一个函数(执行速度尽可能快),当请求停止时返回true,否则返回false。如果是真的,我们保存我们的工作,释放资源并退出。你知道吗

对于一些简单的工具,我实现了以下功能:

  • 在bash中我做了一个touch /tmp/stop
  • 我的Python程序经常轮询/tmp/stop确实存在。如果它以一种可控的方式退出。你知道吗
  • 我的bash脚本等待(loop-sleep-ps),直到相关进程停止。你知道吗

此解决方案可行,但轮询此文件很可能不是最有效的方法。你知道吗

是否有其他开销较小的选项(就Python轮询时间而言)?你知道吗


Tags: 工具方法函数程序功能脚本bashfalse
2条回答

您可以向python进程发送中断信号(SIGINT)。这和你的shell在按下Ctrl+C时发出的信号是一样的:

在Bash中如下所示:

python my_script.py &         # start the script in background
pyscript_pid=$!               # store the python interpreter' PID
sleep(5)                      # pause 5 seconds
kill -s SIGINT $pyscript_pid  # send the SIGINT signal to the process

在Python中,您只需捕获KeyboardInterrupt异常,该异常在解释器接收到SIGINT信号时抛出:

try:
    print ("I'm still running...")
    # do something useful, but it must be interruptible at any time!

except KeyboardInterrupt:
    print ("I'm going to quit now.")

    # tidy up...
    # ... and exit

但是,您不应该执行在try块中中断一半时会中断任何内容的操作,而应该只执行可以中断或重置为整理代码中最后一个有效状态的操作。或者,您可以使用try: ... finally: ...来确保finally块中的代码始终启动,即使try中的代码在运行时被中断。你知道吗

您还可以查看How do I capture SIGINT in Python?或@Robᵩ的答案,以了解如何捕获所有可能的信号,而不仅仅是SIGINT,以及如何为它们注册事件处理程序,而不是使用try-catch(-finally),但这将是最简单的方法。你知道吗

UNIX信号机制将是一个很好的选择。您不需要任何临时文件,轮询开销基本上为零。你知道吗

您可以像这样优雅地关闭以下python程序:kill -USR1 $pid。你知道吗

import signal
import time
import sys

please_stop = False
def setup_signal():
    def handler(x,y):
        global please_stop
        please_stop = True
    signal.signal(signal.SIGUSR1, handler)

def main_task():
    for i in range(10):
        print "Working hard on iteration #%d"%i
        time.sleep(1)
        if please_stop:
            print "Stopping now"
            sys.exit(0)

setup_signal()
main_task()

相关问题 更多 >