l6-d3 守护进程

一、守护进程概念

 

守护进程(Daemon Process)Linux三种进程类型之一

        是 Linux 中的后台服务进程

        是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件

特点:

        始终在后台运行

        独立于任何终端

        周期性的执行某种任务或等待处理特定事件

进程组(Process Group): 进程集合,每个进程组有一个组长(Leader),其进程 ID 就是该进程组 ID。

会话(Session): 一个或多个进程组的集合,每个会话有一个组长,其进程 ID 就是该会话组 ID。

控制终端(Controlling Terminal):每个会话可以有一个单独的控制终端,与控制终端连接的 Leader 就是控制进程(Controlling Process)。终端关闭时,所有相关进程会被结束。

二、守护进程的实现

1.创建子进程,父进程退出

if (fork() > 0)  {

        exit(0);

}

        父进程退出后,子进程变成孤儿进程,被init进程收养

        子进程在后台运行,依然依附于当前终端

2.子进程创建新会话

pid_t setsid(void);

        成功:返回调用进程的会话ID;失败:-1,设置errno。

        子进程成为新的会话组长,脱离原先的终端

        调用了setsid函数的进程,既是新的会长,也是新的组长

3.更改当前工作目录

chdir(“/”);

chdir(“/tmp”);

         守护进程一直在后台运行,其工作目录不能被卸载

4.重设文件权限掩码

if (umask(0) < 0)  {

        exit(-1);

}

        文件权限掩码设置为0

        只影响当前进程

5.关闭打开的文件描述符

int  i;

for(i=0; i<3; i++) {

        close(i);

}

        关闭所有从父进程继承的打开文件

        已脱离终端,stdin / stdout / stderr无法再使用

  重新设定当前工作目录cwd

代码演示1:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(){
  pid_t pid;
  pid = fork();
  if(pid<0){
    perror("fork");
    return 0;

  }else if(pid>0){        //父进程退出
    exit(0);
//    sleep(100);
  }
  printf("I am a deamon\n");
  printf("sid=%d,pid=%d,pgid=%d\n",getsid(getpid()),getpid(),getpgid(getpid()));

  if(setsid()<0){        //创建新会话
    perror("setsid");
    exit(0);
  }  

  printf("after sid=%d,pid=%d,pgid=%d\n",getsid(getpid()),getpid(),getpgid(getpid()));
  
  chdir("/");            //更换工作目录

  if(umask(0)<0){        //重设文件掩码
    perror("umask");
    exit(0);
  }
  
  close(0);
  close(1);
  close(2);
  printf("after close \n");  

  sleep(100);
}

代码演示2:

创建守护进程,每隔1秒将系统时间写入文件time.log

int main(){
    pid_t pid;
    FILE *fp;
    time_t t;
    int i;
    if ((pid = fork()<0){        //创建子进程
        perror("fork"); exit(-1);
        else if (pid>0){        
            exit(0);            //父进程退出
        }
    }

    setsid();            //创建新会话
    umask(0);            //重设掩码
    chdir("/tmp");        //更改工作目录
        
    for(i=0; i<getdtablesize(); i++){        //关闭文件描述符
        close(i);
    }

    if((fp = fopen("time.log","a")) == NULL) {    //打开文件,追加写入
        perror("fopen"); 
        exit(-1); 
    }
    while(1){
        time(&t);        //获取当前系统时间
        fprintf(fp,"%s", ctime(&t));        //转换成本地时间,并写入
        fflush(fp);      //由于流默认全缓冲,fflush刷新缓冲
        sleep(1);
    }
}

三、作业

写出创建守护进程的详细步骤

1.创建子进程,父进程退出;
if (fork()>0){
    exit(0);
}

2.子进程创建新会话;
pid_t setsid(void);

3.更改当前工作目录;
chdir(“/”);

4.重设文件权限掩码,umask;
if (umask(0)<0){
    exit(-1);
}

5.关闭打开的文件描述符;
close(1);
close(2);
close(3);
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值