当前位置: 首页 > Linux

UNIX高级环境编程第13章守护进程

时间:2023-04-06 04:26:50 Linux

简介守护进程:无控制终端,在后台长时间运行的进程编程规则voiddaemonize(constchar*cmd){/**调用umask设置文件模式创建掩码为0。*由继承文件模式创建的掩码可能会拒绝设置某些权限。*/掩码(0);/**调用fork,然后让父进程退出(exit)*1.如果守护进程是作为一个简单的shell命令启动的,那么父进程终止让shell认为命令已经执行*2.子进程继承了父进程的进程组ID,但是有了新的进程ID,保证了子进程不是某个进程组的leader进程*/pid_tpid=fork();如果(pid<0){err_quit(“fork失败。”);}elseif(pid!=0){退出(0);}/**调用setsid来创建一个新的会话,以便调用进程:*a.成为新会话的第一个进程,*b。成为新进程组的领导进程,*c。没有控制终端。*/setsid();结构sigactionsa;sa.sa_handler=SIG_IGN;sigemptyset(&sa.sa_mask);if(sigaction(SIGHUP,&sa,NULL)<0){err_quit("sigaction错误。");}/**终止当前进程,这样后面的代码操作就无法获得终端控制*因为只有sessionleader进程才能获得终端控制。**注:sigaction函数的作用体现在这里:当关闭session的第一个进程时,内核会向session中的所有进程发送一个SIGHUP信号,这个信号默认的处理函数是终止session过程。*/if(pid=fork()){退出(0);}elseif(pid<0){退出(1);}/**将当前工作目录更改为根目录*从父进程继承当前工作目录可能位于挂载的文件系统上。*因为守护进程通常会持续到系统重新启动,*如果守护进程的当前工作目录位于已挂载的文件系统上,则无法卸载文件系统。*这不是安装文件系统的预期目的。*某些守护进程可能会将当前工作目录更改为指定位置并在那里执行它们的工作。*/if(chdir("/")<0){err_quit("chdir失败。");}结构rlimitrl;if(getrlimit(RLIMIT_NOFILE,&rl)<0){err_quit("getrlimit失败。");}/**关闭继承的文件描述符*/if(rl.rlim_max==RLIM_INFINITY){//RLIM_INFINITY是无限限制//TODO:为什么是1024??rl.rlim_max=1024;}for(i=0;i