我有一个服务,比如 foo,用 C++ 编写,以 root 身份运行。有常用的脚本 /etc/init.d/foo start|stop|restart。

在某些时候,foo 需要重新加载自身。通常在升级完成后。但做这样的事情:

system("/etc/init.d/foo restart")

不起作用,因为一旦重新启动杀死了 foo,system() 调用显然也会被杀死,并且重新启动脚本永远不会执行完成。

我是否可以使用另一个调用来代替 system() 作为调用进程的同级进程异步运行,而不是创建同步子进程?

谢谢!

有帮助吗?

解决方案

您是否考虑过 exec[*] 家人了吗?这是一个—— execve.

其他提示

您可以将其放在 inittab 中,让 init 负责在进程因任何原因退出时重新启动该进程。如果您的进程发生崩溃或断言()或意外退出,这也将处理自动重新启动。

然后,为了处理您的用例,该进程将自行终止。

fork() 后面跟着 exec() 怎么样?

考虑实施

/etc/init.d/foo reload

对于你的守护进程(通过我的 Debian 盒子的 grep 判断,这是相当标准的)。

这通常是通过向进程发送 SIGHUP 信号来完成的;守护程序应具有信号处理程序,该信号处理程序捕获此并重新加载任何配置。

如果进程知道需要重新加载,它可以向自己发出信号。

如果您确实需要重新启动以获取新库,那么请使用 exec*()

结合到目前为止的两个答案,使用 分叉执行.

补充一下 Ori 已经说过的,一些 Linux 发行版仍然使用 initab,但 Ubuntu 和其他可能的发行版已经切换到 /etc/event.d。您将一个文件放入其中(复制并编辑现有文件之一),然后使用“sudo start ssh_tunnel”或任何您的文件名称启动守护进程。

然后当你需要它重新启动时,你只需用一个信号杀死它,系统就会重新启动它。或者它可以自己决定是该重新启动的时候,称“退出(0);”管他呢。

exec*() 在原始命令行上单独使用应该可以解决问题。您可能可以省略 fork,因为您有两个不需要的副本正在运行,然后原始副本需要退出。

但还要根据您的发行版查看 inittab 和 event.d,看看它是否能以更好的方式满足您的需要。

Ori 和 Paul 建议的第三种可能性是使用 daemontools。它更便携,但不太可能可用。您创建一个名为 /service/foo/run 的脚本,并且 daemontools 会在服务退出时重新生成您的服务。

http://cr.yp.to/daemontools.html

查看 inittab 的手册页。

它描述了如果进程死亡(重生),系统将如何自动重新启动进程。

正确设置后,您的服务所要做的就是退出,系统将自动为您重新启动(重生)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top