3

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

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

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

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

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

谢谢!

4

9 回答 9

9

你考虑过exec[*]家庭吗?这里有一个—— execve

于 2009-03-09T17:55:07.257 回答
9

您可以将它放在 inittab 中,让 init 在它因任何原因退出时担心重新启动进程。如果您的进程碰巧崩溃或 assert() 或以其他方式意外退出,这也将负责自动重启。

然后,为了处理您的用例,该过程将简单地自行终止。

于 2009-03-09T17:57:29.670 回答
5

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

于 2009-03-09T17:55:58.160 回答
2

考虑实施

/etc/init.d/foo reload

对于您的守护进程(通过我的 Debian 盒子的 grep 判断非常标准)。

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

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

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

于 2009-03-09T20:59:19.200 回答
1

结合到目前为止的两个答案,使用fork-exec

于 2009-03-09T17:57:26.237 回答
1

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

然后当你需要它重启的时候,你可以用一个信号杀死它,系统会重启它。或者它可以通过调用“exit(0);”自行决定是时候重新启动了。管他呢。

于 2009-03-09T18:10:29.980 回答
1

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

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

于 2009-03-09T18:58:27.603 回答
1

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

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

于 2009-03-10T12:26:35.633 回答
0

查看 inittab 的手册页。

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

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

于 2009-03-09T18:44:46.263 回答