守护进程详解

1.守护进程的

概念:系统中的后台进程,周期性的执行某些任务,或者等待某个事件的发生,不会随用户的注销而退出
特点:后台服务进程,不会显示在终端,除了关机和kill,守护进程是不会死的
        独立于控制终端
        周期性执行某任务
        不受用户登录注销影响
        守护进程一般采用以d结尾的名字(服务)

2.进程组
        1.进程组的长?
            组里面的第一进程
            进程组的ID==进程组的组长的ID

3.会话:多个进程组组成的组织叫会话
        1.创建一个会话注意事项
            不能是进程组长
            创建会话的进程称为新进程组的组长
            创建出的新会话会丢弃原有的控制终端
            一般步骤:先fork,父进程死。儿子执行创建会话操作
        2.创建一个会话:pid_t setsid(void)
        3.获取进程所属的会话ID:pid_t getsid(pid_t pid)

4.创建守护进程模型
        1.fork子进程,父进程退出,必须做
        2.子进程创建新会话,必须做,setsid()函数
        3.改变当前工作目录chdir,不是必须的,增强程序的健壮性
        4.重设文件掩码 
            原因:子进程会继承父进程的掩码
            目的:增加子进程程序操作的灵活性
            umask(0);
        5.关闭文件描述符,不是必须的
            子进程脱离终端了,所以需要关闭标准输入,标准输出,标准错误输出
            目的:释放资源
        6.执行核心工作,必须的

5.得到当前时间函数,得到的时间是time_t类型的
        函数原型:time_t time(time_t *tloc)

6.得到的时间格式化

       上面的那个函数得到的是时间是time_t类型,所以我们需要把得到的time_t类型的时间格式化成我们认识的格式

        函数原型:char * ctime(const time_t *time)

  下面看一个守护进程最简单的代码:

  7 int main()
  8 {
  9     pid_t pid = fork();
 10     //创建出子进程,让父进程死
 11     if(pid > 0)
 12     {
 13         exit(0);
 14         //kill(getpid(),SIGKILL);
 15         //raise(SIGKILL);
 16         //abort();       这三个函数都可以杀死父进程
 17     }
 18     else
 19     {
 20         //获取会话id,成为新进程组的组长
 21         setsid();
 22         while(1);
 23     }
 24 
 25     return 0;
 26 }

这就创建出了一个守护进程,在后台运行,不现实在终端

但是可以用ps -aux可以看到这个进程在后台运行

这就说明守护进程在运行,除非你关机或者kill它,否在它会一直存在

接下来看一个题目:写一个守护进程,每隔两秒获取一次系统时间,并将时间写到文件中。

那我们就要按上面的流程来写代码了

  1 #include
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 #include
  8 #include
  9 
 10 void dowork(int n)
 11 {
 12     //获取当前时间,写到磁盘中去
 13     time_t curtime;
 14     time(&curtime);
 15     //格式化时间
 16     char *ptr = ctime(&curtime);
 17     //写到文件中去
 18     int fd = open("file",O_CREAT|O_WRONLY | O_APPEND,0664);
 19     write(fd,ptr,strlen(ptr) + 1);
 20     close(fd);
 21 }
 22 
 23 int main()
 24 {
 25     pid_t pid = fork();
 26     if(pid > 0)
 27     {
 28         exit(0);
 29     }
 30     else if(pid == 0)
 31     {
 32         //子进程成为新的会长,脱离终端,成为守护进程
 33         setsid();
 34         //重新设置文件掩码
 35         umask(0);
 36         //关闭文件描述符
 37         close(0);
 38         close(1);
 39         close(2);
 40 
 41         //执行核心的工作
 42 
 43         //注册信号捕捉
 44         struct sigaction act;
 45         act.sa_flags = 0;
 46         act.sa_handler = dowork;
 47         sigemptyset(&act.sa_mask);
 48         sigaction(SIGALRM,&act,NULL);
 49 
 50 
 51         //创建一个定时器
 52         struct itimerval val;
 53         //第一次触发的时间
 54         val.it_value.tv_usec = 0;
 55         val.it_value.tv_sec = 2;
 56         //循环周期
 57         val.it_interval.tv_usec = 0;
 58         val.it_interval.tv_sec = 1;
 59         setitimer(ITIMER_REAL,&val,NULL);
 60 
 61 
 62         while(1);
 63 
 64     }
 65     return 0;
 66 }

我们运行一下可以看到系统出现了一个file文件,每隔1秒将当前时间写入文件中

守护进程详解_第1张图片

程序仍然在后台运行,那么我们接下来看一下file文件,每一秒写一次

守护进程详解_第2张图片

上面提到了守护进程的特性,除非关机或者kill这个守护进程,否则它会一直运行。所以如果不杀死我们这个程序,那么我们这个程序就会将磁盘写满,所以我们需要杀死这个守护进程。

 

 

 

 

 

 

 

你可能感兴趣的:(linux)