![如何将 C 程序作为守护进程运行?](https://linux22.com/image/19393/%E5%A6%82%E4%BD%95%E5%B0%86%20C%20%E7%A8%8B%E5%BA%8F%E4%BD%9C%E4%B8%BA%E5%AE%88%E6%8A%A4%E8%BF%9B%E7%A8%8B%E8%BF%90%E8%A1%8C%EF%BC%9F.png)
我有一个 C 程序,我想将其作为守护进程运行。如何安装它才能在 CentOS 上作为守护进程运行?有人说用@reboot
,有人说放进去/etc/rc.d/rc.local
。哪一个是正确的方法?
答案1
两者都不。如果您想让它像真正的守护进程一样正常运行,您应该使用 init 系统放置它 - /etc/init.d
(并在适当的/etc/rc.X
文件夹中创建适当的运行级别链接)
运行搜索或查看类似以下内容:https://serverfault.com/questions/204695/compressive-guide-to-init-d-scripts
答案2
假设您正在编写一个网络守护程序,最简单的方法是编写 C 程序来连接xinetd
/inetd
并将守护程序留给xinetd
/inetd
工具。
答案3
如果用户想要编写一些内容来侦听您不想一直运行的网络服务,但仅在需要时才运行,那么您最好在 inetd/xinetd 下运行它,将其与正确的端口关联并运行它那样。
init.d 在各种 *NIX 上也被称为“服务”,用于运行旨在在不同运行级别(例如,启动、关闭、单用户、多用户、网络、没有、有图形界面等)。这些服务旨在持续运行,无论它们是否被访问(例如,像数据库一样)。
例如,数据库将使用 init.d/services/systemctl 启动/停止,因此它会有在多用户+网络启动期间启动它的脚本,并且它会有一个相应的脚本在多用户+网络启动期间正确关闭它。网络关闭之前的关闭过程。这些脚本放置在 /etc/init.d/ 中,并符号链接到正确的运行级别(/etc/init.d/rc2.d = runlevel2、rc3.d = runlevel 3 等)。您可以通过查看“/etc/inittab”文件来确定各种可能的运行级别。您可以通过键入“runlevel”或“uptime”来查看您所处的运行级别,具体取决于您的 *NIX 风格。即使没有人通过网络或本地连接到数据库,数据库也会运行。
但是,如果您有一些小东西,例如 telnet 守护程序、finger 守护程序、whois 守护程序等,它们与操作系统行为的耦合更紧密,并且您不希望它始终位于内存中,只有在需要时才在inetd/xinetd。本质上,inetd/xinetd 是“超级服务器”,当它在特定端口上看到特定类型的连接时,它会启动一个守护进程来处理该消息,然后在单独的端口上重新生成,完成后退出。通过这种方式,您可以生成数百、数千个进程来根据可用的系统资源处理连接。
如果您想将您的 C 程序作为具有 init 运行级别的“服务”运行,那么您将编写程序来执行其功能,然后您将编写一个支持停止参数和停止参数的脚本。然后,您可以将该脚本放入 /etc/init.d/ 中。然后,您将在适当的运行级别目录(例如 rc3.d)中创建一个指向该脚本的符号链接,并且该启动符号链接将以大写“S”开头,这意味着它是活动的并且应该在启动时运行,如果您希望它在该运行级别中的其他任何内容之前运行,则紧随其后的是一个数字,例如“01”;如果您希望它在该运行级别中最后运行,则后面紧跟一个数字“99”。这很重要的原因是您不想启动依赖于其他服务(例如 DNS、NFS 甚至网络)的服务,而这些服务不可用。在这些进程开始后,您可能需要给它一个编号。当系统调用您的脚本 S99domything 时,它会传递单词“start”作为参数 #1,并且在您的脚本内您应该有一个 switch-case,在“start”选择时启动您的进程。如果您想禁用脚本但不删除它,请重命名它,使其以小写的“s”开头(例如“s99domything”)。
同样,要有序关闭进程,您可以在 /etc/init.d/domything 脚本的符号链接前面放置一个“K”,例如 K01domything。现在,如果您需要脚本在其他进程之后启动,当您希望它关闭时,它可能应该在其他进程之前关闭。因此,如果您的启动是 S99domything,那么您的关闭很可能是 K01domything。当 init 进程找到以 K 开头的脚本时,它会在调用该脚本时将第一个参数作为“stop”发送。您的脚本中需要有一个“停止”案例来正确关闭您的服务。
相当聪明。
这也是为什么使用 /sbin/shutdown 很重要,因为它会导致 init 执行正确的启动/关闭顺序,以便一切都以“有序”方式处理,从而减少数据丢失或损坏。
一些例子:
/etc/rc3.d/S25mysql is a symlink to /etc/init.d/mysql.sh
/etc/rc5.d/K01mysql is a symlink to /etc/init.d/mysql.sh
在这两种情况下,符号链接都指向相同的 /etc/init.d 文件,但是当 init 进程启动它们时,它会根据第一个字符是“S”还是“K”来传递“start”或“stop” 。
希望这有助于解释几乎所有 *NIX 风格中与细微变化一致的一些事情。
在更现代的 *NIX 版本中,inetd/xinetd 已经不再受青睐,而不是使用 systemctl/services。这很遗憾,因为它有自己的位置,而且可靠且易于使用。通过查看 /etc/services,您可以了解多年来分配给的所有不同端口。任何端口 1024 或更低的端口都必须由 root 拥有的进程提供服务。
干杯! -D