如何写一个Linux守护进程

2025-07-15 00:29:01

1、创建日志文件,用于记录守护进程的工作日志信息。命令:touch file_name // 创建文件命令:chmod 777 file_name // 修改文件权限为最高

如何写一个Linux守护进程

2、编译源码,生成守护进程的可执行文件。命令:g++ -o output_file source_file // 编译source_file,生成output_fi造婷用痃le备注:源码文件名为demo.cpp

如何写一个Linux守护进程

3、运行,执行守护进程工作任务。命令:./demo // demo是可执行文件名

如何写一个Linux守护进程

4、查看守护进程的日志文件。按预期输出,工作OK。命令:vim file_name // 查看file_name文件。此处为wlm。

如何写一个Linux守护进程

5、查看守护进程信息命令:ps axj | grep "demo" // 查看守护进程信息命令:kill demo_id // 杀掉守护进程

如何写一个Linux守护进程

6、守护进程源码实现注:最后一步,将提供可复制的源码。

如何写一个Linux守护进程
如何写一个Linux守护进程
如何写一个Linux守护进程
如何写一个Linux守护进程

7、/***********************************************涯箨唁峦************************** 开发守护进程**********忮氽阝另*************************************************************/#include <stdio.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <sys/param.h>#include <sys/stat.h>#include <time.h>#include <syslog.h>#include <sys/resource.h> // use getrlimit#include <signal.h> // use sigaction#include <stdlib.h> // use exit,systemvoid create_daemon(void){ // 文件描述符 int i, fd0, fd1, fd2; // 进程ID pid_t pid; // 资源限制 struct rlimit rl; // 信号动作 struct sigaction sa; // // 函数:umask // 功能:设置文件模式的屏蔽属性。即,通过umask可禁掉某些属性。 // // 目的:调用umask将文件模式创建屏蔽字设置为0,确保所有文件模式可用。 // umask(0); // // 函数:getrlimit(RLIMIT_NOFILE, **); // 功能:获取资源限制,RLIMIT_NOFILE表示每个进程能打开的最大文件数。 // // 目的:获取文件描述符的信息 // if(getrlimit(RLIMIT_NOFILE, &rl) < 0){ printf("can not get file limit"); return; } // // 函数:fork // 功能:创建子进程。子进程继承父进程的进程组ID,但具有一个新的进程ID。 // 这确保了,子进程不是一个进程组的组长进程。 // // 函数:setsid // 功能:创建新会话,当前进程是,新会话首进程,也是新会话的唯一进程。该进程 // 会成为一个新进程组的组长进程,新进程组ID就是该调用进程的进程ID // 注意:如果调用进程是一个进程组的组长,则此函数会返回出错。为了确保不会 // 发生这种情况,通常先调用fork,然后使其父进程终止,而子进程则继续。 // // 目的:使得目标调用进程,达到以下目的。 // a) 成为新会话的首进程 // b) 成为一个新进程组的组长进程 // c) 没有控制终端 // if((pid = fork()) < 0){ printf("can not fork"); return; }else if(pid != 0){ exit(0); } setsid(); // // 函数:sigemtpyset(sigset_t *set) // 功能:初始化由set指向的信号集,清楚其中所有信号。 // // 函数:int sigaction(int signo, const struct sigaction * restrict act, struct sigaction *restrict oact); // 功能:检查或者修改与指定信号相互关联的处理动作。其中,参数signo是要检测或修改其具体动作的信号编号。 // 若act指针非空,则要修改其动作。如果oact指针非空,则系统经由oact指针返回该信号的上一个动作。 // 注意:SIG_IGN是常量,用于代替指向函数的指针。该函数需要一个整型参数,而且无返回值。 // #define SIG_DFL (void (*)())0 // #define SIG_IGN (void (*)())1 // // 目的:忽略连接断开信号SIGHUP // sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if(sigaction(SIGHUP, &sa, NULL) < 0){ printf("can not ignore SIGHUP"); return; } // 目的:再次fork,并使父进程终止。第二个子进程作为守护进程继续运行。这样就保证了该守护进程不是会话首进程。 // 可以防止它取得控制终端。 if((pid = fork()) < 0){ printf("can not fork"); return; }else if(pid != 0){ exit(0); } // // 函数:chdir // 功能:更改当前动作目录。当前工作目录是进程的一个属性。此目录是搜索相对路径名的起点。 // // 目的:使得进程不与任何文件系统联系。 if(chdir("/usr/wlm/dev") < 0){ printf("can not change directory"); return; } // 目的:关闭不再需要的文件描述符。这使守护进程不再持有从其父进程继承来的某些文件描述符。 if(rl.rlim_max == RLIM_INFINITY){ rl.rlim_max = 1024; } for(i = 0;i< rl.rlim_max; i++){ close(i); } // // 函数:int open(const char * pathname, int oflag, ...); // 功能:打开或者创建一个文件。O_RDWR表示“读,写打开” // // 函数:int dup(int filedes); // 功能:复制一个现存的文件描述符,返回的新文件描述符一定是当前可用文件描述符中的最小数值。 // 通常等于输入的文件描述符+1; // // 目的:守护进程打开/dev/null使其具有文件描述符0,1,2。这样,任何一个试图读标准输入, // 写标准输出,或者标准出错的例程都不会产生任何效果。因为守护进程并不与终端设备 // 相关联,所以不能在终端设备上显示其输出,也无处从交互式用户那里接收输入。 fd0 = open("/dev/null", O_RDWR); fd1 = dup(0); fd2 = dup(0); if(fd0 != 0 || fd1 != 1 || fd2 != 2){ printf("unexpected file descriptors %d %d %d", fd0, fd1, fd2); exit(1); } // 重点:守护进程做任务 // // 函数:int system(const char * cmdstring); // 功能:执行一个命令字符串。 // 示例:system("date > file"); // system("echo \"hello,world!\\n\" >> wlm"); time_t now; while(1){ sleep(30); // // 函数:FILE * fopen(const char * restrict pathname, const char * restrict type); // 功能:打开一个标准I/O流 // 注意:type="r+ 或r+b 或rb+",表示为读写而打开。 // type="a+", 表示open or create for reading and writing at end of file // FILE * fd = fopen("wlm", "a+"); // // 函数:time_t time(time_t * calptr); // 功能:返回当前时间和日期 // 注意:返回时间值。如果参数不为空,则时间值也存放在由calptr指向的单元内 // time(&now); // // 函数:int fprintf(FILE *restrict fp, const char *restrict format, ...); // 功能:写至指定的流 // fprintf(fd, "system time:\t%s\t\t pid:%d\n", ctime(&now), getpid()); fclose(fd); }}int main(){ printf("hello,welcome to create daemon.\r\n"); // 创建守护进程 create_daemon(); return 0;}

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢