守护进程介绍

    技术2022-05-11  53

    【守护进程介绍】

    Linux系统启动时往往要启动很多的系统服务程序,比如apache,ftp,telnet等。这些系统服务程序往往运行在后台,没有控制终端,在系统引导装入时启动,在系统关闭时终止,周期性的执行某项任务或者等待处理某项任务。这样的进程叫守护进程或者精灵进程。

     

    编写守护进程一般是在普通进程基础上,根据守护进程的特点进行改造。编程实现守护进程要遵循的几个要点:

     

    1.父进程是init进程,后台执行

    用fork函数创建子进程,并将父进程终止,这样子进程成为孤儿进程被init进程收养,并在后台执行。

     

    2.脱离控制终端,创建新的会话和进程组,并成为首进程

    进程组是一个或者多个进程的集合,进程组有对应的组ID,是由领头进程的进程号决定的;会话是一个或者多个进程组的集合,每个会话也有一个领头进程。每个进程属于一个进程组,每个进程组又属于一个会话。当用户从终端登陆系统时,系统会创建一个会话,该终端上启动的进程都会被系统规划到会话的进程组中。会话中的进程是通过会话的领头进程与一个控制终端相连。

     

    由于守护进程没有控制终端,而通过fork创建的子进程继承了父进程的控制终端、进程组和会话,因此必须重新创建会话,以脱离父进程的影响。

    pid_t setsid(void);  //返回调用进程的会话ID

    前提:调用setsid的进程不能为一个进程组的领头进程,fork的子进程一定满足

    结果:创建新的会话,调用setsid的子进程成为会话中唯一进程组,组ID=调用进程的ID.

     

    3.更改当前工作目录

    fork的子进程继承父进程的工作目录,但是如果作为守护进程使用,进程没有结束之前,工作目录不能被卸载。所以一般将工作目录使用chdir()更改到根目录下。

     

    4.关闭文件描述符,重定向标准输入、输出、错误

    需要关闭从父进程继承来的无需使用的文件描述符。运行在后台,不需要在终端有任何输出信息。

     

    5.重设权限

    屏蔽其他用户对守护进程创建的临时文件的访问权限。

     

    【代码实现】

    #include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <fcntl.h>#include <sys/stat.h>#include <stdlib.h>

    void daemon_def(void){ pid_t pid; int fd; pid = fork(); if(pid<0) {  perror("Fail to creat child process./n");  return;

     } else if(pid>0) {  exit(0); } else {  pid = setsid();  if(pid<0)  {   perror("Setsid failed./n");   return;  }  chdir("/");  if((fd = open("/dev/null",O_RDWR,0))==-1)  {   perror("Can't open dev file./n");   return;  }  dup2(fd,STDIN_FILENO);  dup2(fd,STDOUT_FILENO);  dup2(fd,STDERR_FILENO);  umask(0027);  return;   //这里错用成exit,子进程直接终止了,即main没有执行到sleep就结束了。ps看不到。   }}

     

    int main(void){ daemon_def(); sleep(1000); return 0;}


    最新回复(0)