可安装的Linux守护进程,如何用C ++创建它们?
我在C ++中有一个服务器应用程序,我希望它的行为与Windows服务相同。即,无论用户是否登录,系统启动时都应启动它。在Windows中,有许多C ++类能够促进与服务管理器的通信并处理启动/停止/暂停命令。 Linux怎么样?另外,我如何轻松部署我的应用程序?我羡慕如何使用apt-get system命令安装一些应用程序,这对于自定义应用程序来说很容易,比如我在一台机器上提供二进制文件然后自动从目标Linux中获取它们??< / p>
提前感谢您的帮助。
答案 0 :(得分:8)
好的,首先,你需要知道在Windows和Linux中编写服务是非常不同的。首先,在Linux中,“服务”不称为“服务”,它们被称为“守护进程”。知道了,您可以使用谷歌find this extremely useful document。
至于启动/停止/重启,这里没有通用的预制解决方案。在大多数情况下,守护进程在/ var / run中创建* .pid文件;这些文件包含其进程标识符“PID”。然后编写一个简单的bash脚本,通过从相应的文件中读取pid并向其发送一个kill信号来控制守护程序的执行。
例如,假设您的守护程序名称为foo
。然后它将创建文件/var/run/foo.pid并将其PID写入其中,使用ASCII字符并在末尾附加换行符。您的控制脚本名称为fooctl
,它应支持以下命令:start,stop和restart。也就是说,当你运行fooctl start
时,脚本应首先检查相应的pid文件是否存在,如果不存在,则执行启动守护进程所需的任何操作;当你运行fooctl stop
时,它应该从/var/run/foo.pid读取pid并使用该ID终止进程。如果是fooctl restart
,您的脚本将需要先停止守护进程,然后再次启动它。
尽管如此,这只是关于守护进程应该如何工作的协议。这就是通常的做法。但这些规则并未以任何方式强制执行。您可以自由地发明并使用自己的技术来创建和控制守护进程。
关于问题的第二部分(关于apt-get),这称为包管理。它与守护进程无关,但是由于您要求:使用自定义应用程序执行此操作,您需要将其发布到主存储库中,这可能由于多种原因而无法实现;或者你可以创建自己的回购。您也可以为您的应用程序组装一个* .deb包,它也很容易安装。在网上搜索有关如何为自定义Linux应用程序构建包的更多信息。
答案 1 :(得分:0)
在linux中,守护进程本质上是无接口程序。它在代码中没有特殊的差异。 令人遗憾的是,将程序自动启动为守护进程是以不同的方式在不同的发行版上完成的。对于Ubuntu,请阅读有关运行级别和upstart / plymouth系统的信息。您必须构建一个包文件来为您进行设置,而不是程序。
答案 2 :(得分:0)
Deamons就像其他人一样。例外,他们没有父母(或他们的父母是进程0),没有组ID,没有会话ID。理查德史蒂文斯(在Unix环境下进行系统编程时,仍然推荐 Unix环境中的高级编程)将此功能作为一种设置方式:
if ( (pid = fork()) < 0) {
return -1;
else if (pid == 0) {
exit(0);
setsid();
chdir("/");
umask(0);
但它仍然没有处理一些问题(例如,关闭继承的文件句柄,主题在本书的其他地方处理)。
然后存在控制deamon的问题。有些惯例很常见(但不是通用的):
- writing its pid in a file under /var/run/
- handling SIGHUP as a way to reread its configuration file
- using the syslog system to log messages
Linux发行版也有控制守护程序的常用方法。这些通常通过与deamon一起安装的脚本来处理,它将分发约定转换为deamon正确使用的内容。
答案 3 :(得分:0)
尝试使用此link。它包含A-Z守护程序编写。
首先,您需要在Linux上安装以下软件包 机器开发守护进程,具体来说:
GCC 3.2.2 或更高版本以及 Linux开发标题和库
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
int main(void) {
/* Our process ID and Session ID */
pid_t pid, sid;
/* Fork off the parent process */
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
/* Change the file mode mask */
umask(0);
/* Open any logs here */
/* Create a new SID for the child process */
sid = setsid();
if (sid < 0) {
/* Log the failure */
exit(EXIT_FAILURE);
}
/* Change the current working directory */
if ((chdir("/")) < 0) {
/* Log the failure */
exit(EXIT_FAILURE);
}
/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
/* Daemon-specific initialization goes here */
/* The Big Loop */
while (1) {
/* Do some task here ... */
sleep(30); /* wait 30 seconds */
}
exit(EXIT_SUCCESS);
}