守护进程及其范例代码

守护进程理解以及与后台进程区别

守护进程,也就是常说的Daemon进程,是一种长期运行在linux后台的服务进程,并且不与任何控制终端关联。

守护进程的特点

  1. 生存周期长,只随着系统的开始、关闭而开启、关闭;
  2. 守护进程和终端没有直接关联;
  3. 后台运行

与后台进程的区别

守护进程与后台进程的区别主要体现在与终端的关联性上:

  1. 后台进程: 当终端退出时,后台进程也随之关闭;
  2. 守护进程: 守护进程既不会在终端上输出、输入,也不会因为终端的退出而退出

守护进程编写规则

在了解守护进程是如何编写之前,先要了解下面三个内容

  • 文件描述符
  • 输入输出重定向
  • 空设备

文件描述符

文件描述符:正数,用来标识一个文件,当打开一个存在的文件或者创建一个新文件,操作系统都会返回一个文件描述符。可以理解为这个文件描述符就是代表这个文件的,后续对这个文件进行操作的函数,都会用到这个文件描述符作为参数。

Linux下三个特殊的描述符(数字0、1、2)

  • 数字0: 标准输入(键盘) 对应的符号常量(宏定义STDIN_FILENO
  • 数字1: 标准输出(屏幕)对应的符号常量(宏定义STDOUT_FILENO
  • 数字2: 标准错误 (屏幕)对应的符号常量(宏定义STDERR_FILENO

从我个人理解上来说,Linux下一切皆文件,有以下面三点

  • 要像看待/操作文件一样去看待/操作文件描述符;
  • 程序运行的同时,这三个文件描述符 0、1、2 会被自动打开,自动指向对应的设备(键盘、屏幕、屏幕);
  • 可以把文件描述符看做一个指针,去指向他们代表的文件。

在这里插入图片描述

输入输出重定向

输出重定向

让标准输出文件描述符不再指向屏幕,而是去指向另一个文件。

//命令行示例:
ls -la > myoutfile

随便打开一个目录,命令行ls -la 查看目录文件信息
在这里插入图片描述
输出重定向到myoutfile文件
在这里插入图片描述
观察myoutfile文件内容发现,原本输出到屏幕的内容输出到了文件中

//观察myoutfile文件内容:
cat myoutfile

在这里插入图片描述

输入重定向

// An highlighted block
cat < myinfile

类似于输出重定向,输入重定向就是将从键盘输入数据改为从myinfile文件输入,cat将从myinfile文件中获取的数据显示到屏幕上。


空设备

目录位置:/dev/null
功能:类似于黑洞,丢弃一切写入其中的数据。

守护进程虽然可以从终端启动,但是和终端不挂钩,守护进程在后台运行,但是不应该从键盘上接受任何数据,也不应该把输出结果打印到屏幕上或者终端上来,所以,要把守护进程的标准输入,标准输出重定向到空设备中去!


代码范例

int ngx_daemon()
{
    int fd;
    
    switch(fork())
    {
        case -1:
            //创建子进程失败。记录错误日志
            return-1;
        case 0:
            //成功创建子进程。
            break;
        default:
            //父进程,直接退出。
            exit(0);
    }
    //只有子进程才能走到这里,只有子进程才能break退出。
    if(setsid()==-1) //脱离终端,终端关闭,也与此子进程无关。
    {
        //记录错误日志
        return -1;
    }

    umask(0);//设置为0,不让它来限制文件权限,以免引起混乱。

    fd=open("/dev/null",O_RDWR);//打开黑洞设备,以读写形式。

    if(fd==-1)
    {
        //记录错误日志。
        return -1;
    }

    if(dup2(fd,STDIN_FILENO)==-1) //先关闭STDIN_FILENO,如果之前已经打开
                                     //则将其关闭
    {
        //记录错误日志。
        return -1;
    }
    if(dup2(fd,STDOUT_FILENO)==-1) //同样也是先关闭STDOUT_FILENO.
    {
        //记录错误日志。
        return -1;
    }
    if(fd>STDERR_FILENO)//fd应该是3,这里应该成立
    {
        if(close(fd)==-1)
        {
            //记录错误日志。
            return -1;
        }
    }
    return 1;
}


int main(int argc, char *const *argv)
{
    if(ngx_daemon()!=1)
    {
        //创建守护进程失败。
        return -1;
    }
    else
    {
        for(;;)
        {
            sleep(1);
            printf("---休息1秒---进程id=%d\n",getpid());
            //现在标准输出已经重定向到黑洞中去,打印也看不到结果。
        }
    }
    
    printf("再见!\n");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值