Linux守护进程

Linux守护进程

1) 守护进程也称为Daemon进程,是Linux中的后台服务进程。守护进程用于执行特定的系统任务。守护进程的生命周期较长,一些守护进程在系统引导时启动,一直运行至系统关闭。

2) Linux系统大多数服务都是用守护进程实现的。

 

1. 查看系统中的守护进程

ps -axj

父进程ID       PPID

进程ID          PID

进程组ID       PGID

会话期ID       SID

终端ID          TTY

终端进程组ID       TPGID

状态              STAT

用户              UID

运行时间       TIME

指令              COMMAND

 

2. Linux守护进程编写步骤

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

2)在子进程内创建新会话

3)改变工作目录

4)重设文件权限掩码

5)关闭文件描述符

 

具体步骤如下:

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

当父进程退出后,子进程变成了孤儿进程。在Linux内,如果出现了孤儿进程,则自动由1号进程(init进程)收养该进程,也就是说变成了1号进程(init进程)的子进程了。

pid = fork();

If(pid > 0)

{

       exit(0);

}

2. 在子进程内创建新会话

首先需要了解两个概念:进程组与会话期

进程组:

进程组是一个或多个进程的集合。进程组号由PGID(Process Group ID)唯一识别。

进程不是孤立的,每个进程都存在父子、兄弟关系,如果某些进程关系相近或者功能相似,那么我们可以将这些进程编成一个进程组。每个进程必定属于一个进程组,也只能属于一个进程组。

每个进程组都有一个组长进程,负责整个进程组的调度工作。组长进程的PID等于进程组的PGID。

会话期:

会话期是一个或多个进程组的集合。

可以使用setsid()函数来创建一个新会话,并让该进程担任会话组长。调用setsid()函数主要有三个功能:

1)让进程摆脱原会话控制

2)让进程摆脱原进程组控制

3)让进程摆脱原控制终端控制

 

3. 改变工作目录

使用fork()函数创建的子进程复制了父进程的工作目录。由于在进程运行过程中,当前进程的工作目录所在的文件系统是无法卸载的,这会对后续的工作造成一定麻烦(例如需要切换到单用户模式),因此在后台工作的守护进程的工作目录必须改变成其他的不会受到干扰的工作目录。通常情况下,我们将守护进程的工作目录设定为根目录"/"或”/tmp”。

chdir()可以改变进程当前工作目录。

 

4. 重设文件权限掩码

文件权限掩码是指文件权限中被屏蔽掉的对应位。把文件权限掩码设置为0,可以增加该守护进程的灵活性。

设置文件权限掩码的函数为umask()。

通常使用umask(0)。

 

5. 关闭文件描述符

新建的子进程会从父进程那里继承所有打开的文件。

在创建完新的会话后,守护进程已经脱离任何控制终端,应当关闭应用不到的文件。

fdtablesize = getdtablesize();

for(fd = 0; fd < fdtablesize; fd++)

       close(fd);

 

示例:建立一个守护进程,该进程每隔1 秒向/tmp/daemon.log写入date

示例代码:

/*************************************************************************

 @Author: wanghao

 @Created Time : Mon 21 May 2018 05:33:56 AMPDT

 @File Name: daemon_demo.c

 @Description:

 ************************************************************************/

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <stdlib.h>

#include <stdio.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <string.h>

#include <time.h>

 

 

#define N 128

 

 

int main()

{

       FILE*fp;

       pid_tpid;

       inti, fd;

       int   line = 0;

       char buf[N];

 

 

       pid= fork();

       if(pid < 0) {

              printf("Errorfork\n");

              exit(1);

       }

      

       if(pid > 0)

       {

              exit(0);   

       }

 

 

       setsid();

       chdir("/");             

       umask(0);

       for(i= 0; i < getdtablesize(); i++)

       {

              close(i);

       }

      

       if((fp = fopen("/tmp/daemon.log", "a+")) < 0)              

       {

              exit(1);

       }

 

 

       while(fgets(buf, N, fp)!= NULL)

       {     

              line++;

       }

       while(1){

 

 

              time_tt;

              /*Getthe  time as  the  number of seconds since the Epoch,

               1970-01-01 00:00:00 +0000 (UTC).*/

              time(&t);

              structtm *t1;

              /*Getthe current local time*/

              t1=localtime(&t);

             

              if(sprintf(buf, "%-2d %d/%d/%d %d:%d:%d\n",

                     ++line,

                     t1->tm_year+1900,

                     t1->tm_mon+1,

                     t1->tm_mday,

                     t1->tm_hour,

                     t1->tm_min,

                     t1->tm_sec)< 0)

              {

                     perror("fprintferror");

                     break;

              }

 

 

              printf("%s",buf);

              fputs(buf,fp);

             

              fflush(fp);

              sleep(1);

       }

      

       exit(0);

}

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值