c编写linux守护进程,C++编写LINUX守护进程的实现代码

c编写linux守护进程,C++编写LINUX守护进程的实现代码

2023年8月2日发(作者:)

c编写linux守护进程,C++编写LINUX守护进程的实现代码1、什么是守护进程守护进程是运⾏在后台的⼀种特殊进程,它独⽴于控制终端并且周期性地执⾏某种任务或循环等待处理某些事件的发⽣;守护进程⼀般在系统启动时开始运⾏,除⾮强⾏终⽌,否则直到系统关机才随之⼀起停⽌运⾏;守护进程⼀般都以root⽤户权限运⾏,因为要使⽤某些特殊的端⼝或者资源;守护进程的⽗进程⼀般都是init进程,因为它真正的⽗进程在fork出守护进程后就直接退出了,所以守护进程都是孤⼉进程,由init接管;2、有哪些常见的守护进程⽇志服务进程 syslogd数据库守护进程 mysqld3、创建守护进程的步骤(1) fork()创建⼦进程,⽗进程exit()退出这是创建守护进程的第⼀步。由于守护进程是脱离控制终端的,因此,完成第⼀步后就会在Shell终端⾥造成程序已经运⾏完毕的假象。之后的所有⼯作都在⼦进程中完成,⽽⽤户在Shell终端⾥则可以执⾏其他命令,从⽽在形式上做到了与控制终端的脱离,在后台⼯作。(2) 在⼦进程中调⽤ setsid() 函数创建新的会话在调⽤了fork()函数后,⼦进程全盘拷贝了⽗进程的会话期、进程组、控制终端等,虽然⽗进程退出了,但会话期、进程组、控制终端等并没有改变,因此,这还不是真正意义上的独⽴开来,⽽ setsid() 函数能够使进程完全独⽴出来。(3) 再次 fork() ⼀个孙进程并让⼦进程退出为什么要再次fork呢,假定有这样⼀种情况,之前的⽗进程fork出⼦进程以后还有别的事情要做,在做事情的过程中因为某种原因阻塞了,⽽此时的⼦进程因为某些⾮正常原因要退出的话,就会形成僵⼫进程,所以由⼦进程fork出⼀个孙进程以后⽴即退出,孙进程作为守护进程会被init接管,此时⽆论⽗进程想做什么都随它了。(4) 在孙进程中调⽤ chdir() 函数,让根⽬录 ”/” 成为孙进程的⼯作⽬录这⼀步也是必要的步骤,使⽤fork创建的⼦进程继承了⽗进程的当前⼯作⽬录。由于在进程运⾏中,当前⽬录所在的⽂件系统(如“/mnt/usb”)是不能卸载的,这对以后的使⽤会造成诸多的⿇烦(⽐如系统由于某种原因要进⼊单⽤户模式)。因此,通常的做法是让"/"作为守护进程的当前⼯作⽬录,这样就可以避免上述的问题,当然,如有特殊需要,也可以把当前⼯作⽬录换成其他的路径,如/tmp,改变⼯作⽬录的常见函数是chdir。(5) 在孙进程中调⽤ umask() 函数,设置进程的⽂件权限掩码为0⽂件权限掩码是指屏蔽掉⽂件权限中的对应位。⽐如,有个⽂件权限掩码是050,它就屏蔽了⽂件组拥有者的可读与可执⾏权限。由于使⽤fork函数新建的⼦进程继承了⽗进程的⽂件权限掩码,这就给该⼦进程使⽤⽂件带来了诸多的⿇烦。因此,把⽂件权限掩码设置为0,可以⼤⼤增强该守护进程的灵活性。设置⽂件权限掩码的函数是umask。在这⾥,通常的使⽤⽅法为umask(0)。(6) 在孙进程中关闭任何不需要的⽂件描述符同⽂件权限码⼀样,⽤fork函数新建的⼦进程会从⽗进程那⾥继承⼀些已经打开了的⽂件。这些被打开的⽂件可能永远不会被守护进程读写,但它们⼀样消耗系统资源,⽽且可能导致所在的⽂件系统⽆法卸下。在上⾯的第2)步之后,守护进程已经与所属的控制终端失去了联系。因此从终端输⼊的字符不可能达到守护进程,守护进程中⽤常规⽅法(如printf)输出的字符也不可能在终端上显⽰出来。所以,⽂件描述符为0、1和2 的3个⽂件(常说的输⼊、输出和报错)已经失去了存在的价值,也应被关闭。(7) 守护进程退出处理当⽤户需要外部停⽌守护进程运⾏时,往往会使⽤ kill 命令停⽌该守护进程。所以,守护进程中需要编码来实现 kill 发出的signal信号处理,达到进程的正常退出。4、守护进程的代码实现#include#include#include#include#include#include#include#includestatic bool flag = true;void create_daemon();void handler(int);int main(){time_t t;int fd;create_daemon();struct sigaction act;_handler = handler;sigemptyset(&_mask);_flags = 0;if(sigaction(SIGQUIT, &act, NULL)){printf("sigaction error.n");exit(0);}while(flag){fd = open("/home/mick/",O_WRONLY | O_CREAT | O_APPEND, 0644);if(fd == -1){printf("open errorn");}t = time(0);char *buf = asctime(localtime(&t));write(fd, buf, strlen(buf));close(fd);sleep(60);}return 0;}void handler(int sig){printf("I got a signal %dnI'm quitting.n", sig);flag = false;}void create_daemon(){pid_t pid;pid = fork();if(pid == -1){printf("fork errorn");exit(1);}else if(pid){exit(0);}if(-1 == setsid()){printf("setsid errorn");exit(1);}pid = fork();if(pid == -1){printf("fork errorn");exit(1);}else if(pid){exit(0);}chdir("/");int i;for(i = 0; i < 3; ++i){close(i);}umask(0);return;}5、⽤系统函数daemon实现#include#include#include#include#include#include#include#includestatic bool flag = true;void handler(int);int main(){time_t t;int fd;if(-1 == daemon(0, 0)){printf("daemon errorn");exit(1);}struct sigaction act;_handler = handler;sigemptyset(&_mask);_flags = 0;if(sigaction(SIGQUIT, &act, NULL)){printf("sigaction error.n");exit(0);}while(flag){fd = open("/home/mick/",O_WRONLY | O_CREAT | O_APPEND, 0644);if(fd == -1){printf("open errorn");}t = time(0);char *buf = asctime(localtime(&t));write(fd, buf, strlen(buf));close(fd);sleep(60);}return 0;}void handler(int sig){printf("I got a signal %dnI'm quitting.n", sig);flag = false;}以上就是C++实现LINUX守护进程代码实例的详细内容,更多关于C++ LINUX守护进程的资料请关注脚本之家其它相关⽂章!

发布者:admin,转转请注明出处:http://www.yc00.com/news/1690955747a472427.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信