linux守护进程daemon

linux守护进程:


linux很多的系统服务都是守护进程,例如本地的系统服务crond计划任务 , 网络服务:web httpd


如何将一个进程转换为守护进程呢?




一.概念:
    进程:
每一个进程都有父进程(祖先进程是INIT进程 ,PID 1)相关系统调用 fork();
子进程终止,父进程会得到通知,并且获取子进程的退出状态:相关:wait()




    进程组:
每个进程也属于一个进程组;
每个进程组也有一个ID,ID是组长的PID;
一个进程只能为自己和子进程设置进程ID;

    会话期(session):
     会话期是一个或者多个进程组的集合;
    setsid()可以建立一个会话期
    如果setsid不是进程组的组长的话,会创建一个新的会话期.
    1.此进程编程新的会话期的首进程组
    2.此进程编程新的进程组的组长
    3.脱离控制终端的关系


   如果是子进程的组长的话,返回错误
   为了保证这一点,所以我们先调用fork 然后再调用  exit
  
    代码:
pid_t pid,sid;
pid = fork();
if(pid < 0)
{
  exit(-1);//error
}
else if(pid > 0)
{
  exit(0);//father exit(0)
}
else 
{
   sid = setsid();//child create
}
  ......


二.守护进程的特性
1.在后台运行的;
2.与当前的环境隔离开来,关闭文件描述符,控制终端,会话,以及文件掩码等等
3.启动方式  /etc/rc.d    /etc/init.d/   shell  crond(计划任务)



三.
    编程要点:
      1. pid = fork();
if(pid > 0)
{
  exit(0);
}//关闭父进程


      2. 脱离控制终端,登陆会话和进程组
以上都从父进程中继承来的,必须要摆脱他们,使之不受影响;
setsid();//一个函数搞定
    
/*关系  一对多


会话-》进程组-》进程*/
***失败原因:进程本来就是进程组的组长,但是第一步已经避免了


       3.关闭打开的文件描述符
系统默认打开的文件描述符  标准输入,标准输出,标准错误(0,1,2);
 close(STDIN_FILENO);标准输入
close(STDOUT_FILENO);标准输出
close(STDERR_FILENO);标准错误




4.改变当前目录
 进程活动时,当前的工作目录所在的文件系统是不能卸载的,所以一般改工作目录到'/'  root
chdir("/");




5.重新设置文件掩码umask


 进程从创建的父进程哪里继承了文件掩码,所以需要重设umask(0);


       
以上基本上就完成了整个守护进程的操作;




代码实例:

void init_daemon()
{
        pid_t pid,sid;
        pid = fork();
        if(pid < 0)
        {
          exit(-1);
        }
        else if(pid > 0)
        {
            exit(0);
        }
        else
        {
           sid = setsid();
        }
        chdir("\");
        umask(0);
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
}


 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章