0

我有两个脚本:“autorun.py”和“main.py”。我将“autorun.py”作为服务添加到我的 linux 系统中的自动运行中。完美运行!

现在我的问题是:当我想从我的自动运行脚本启动“main.py”,并且“main.py”将永远运行时,“autorun.py”也永远不会终止!所以当我这样做的时候

sudo service autorun-test start

该命令也永远不会完成!

如何运行“main.py”然后退出,并完成它,当使用参数“stop”启动“autorun.py”时如何停止“main.py”?(这就是我认为所有其他服务的工作方式)

编辑:

解决方案:

if sys.argv[1] == "start":
    print "Starting..."
    with daemon.DaemonContext(working_directory="/home/pi/python"):
        execfile("main.py")
else:
    pid = int(open("/home/pi/python/main.pid").read())
    try:
        os.kill(pid, 9)
        print "Stopped!"
    except:
        print "No process with PID "+str(pid)
4

1 回答 1

1

首先,如果你想创建一个系统守护进程,你几乎肯定想要遵循PEP 3143,并且你几乎肯定想要使用该daemon模块来为你做这件事。

当我想从我的自动运行脚本启动“main.py”并且“main.py”将永远运行时,“autorun.py”也永远不会终止!

你没有说你是如何运行它的。如果您正在做任何main.py作为孩子启动并等待的事情(或者,更糟糕的是,尝试import/ execfile/etc. 在同一进程中),您就不能这样做。要么autorun.py必须启动和分离main.py(或通过某些外部工具间接这样做),要么main.py必须在启动时进行守护进程。

当使用参数“stop”启动“autorun.py”时,如何停止“main.py”?

您需要某种形式的进程间通信 (IPC),以及autorun找到要使用的正确 IPC 通道的某种方式。

如果您正在构建网络服务器,正确的答案可能是作为客户端连接到它。但除此之外,最简单的做法是kill带有信号的进程。

如果您正在使用该daemon模块,它可以轻松地将信号映射到回调。或者,如果您不需要任何清理,只需使用SIGTERM,默认情况下会突然终止。如果这些都不适用,您将不得不设置一个自定义信号处理程序(并在该处理程序中做一些有用的事情——例如,设置一个您的主代码定期检查的标志)。

你怎么知道将信号发送到哪个进程?执行此操作的标准方法是main.py在启动时将其 PID 记录在 pidfile 中。你读了那个 pidfile,并用信号通知那里指定的任何进程。(如果您因为没有具有该 PID 的进程而收到错误,那仅表示守护程序已因某种原因退出 - 可能是因为未处理的异常,甚至是段错误。您可能想要记录它,但处理“停止" 否则成功。)同样,如果你使用daemon,它会为你做 pidfile 的东西;如果没有,你必须自己做。

您可能想查看计算机附带的守护程序的服务脚本。它们可能都是用 bash 而不是 Python 编写的,但要弄清楚它们在做什么并不难。或者……只需将其中一个用作骨架,在这种情况下,您实际上并不需要任何bash 知识;它只是名称上的搜索和替换。

如果你的发行版有 LSB 风格的初始化函数,你可以使用类似这个例子的东西。那个比你需要做的要多得多,但它是所有细节的一个很好的例子。或者用这个例子从头开始做这一切。daemon这个是从服务脚本进行pidfile管理和后台处理(将非守护程序转换为守护程序),如果您使用得当,则不需要这些,它使用的是SIGHUP而不是SIGTERM。您可以自行搜索 init.d 服务脚本的其他示例。

但是同样,如果您只是想为自己的系统执行此操作,最好的办法是查看您的发行版上的 /etc/init.d。那里将有几十个示例,其中 90% 将完全相同,除了守护程序的名称。

于 2013-04-05T01:27:38.613 回答