linux c++ 通信架构 笔记(13) 第三章 Nginx 开发初步:守护进程及其范例创建代码,命令 touch,umask,输入输出重定向,字符设备黑洞文件 /dev/null,函 dup2()

(80) 守护进程,其实就是不占有终端 shell 的会话进程。通常可以由 shell 创建一个父进程,父进程再创建一个子进程,子进程调用 setsid() 函数,使得自己成为会话首领,且不占有终端。这时子进程就成为了守护进程。其 ppid 是 不变的。但在其父进程关闭后,其会成为 1 号进程的子进程。

在这里插入图片描述

(81) 观察系统的守护进程的情况:

在这里插入图片描述

(82) 学习一个新命令 touch ,创建新的空文件。(创建目录的命令是 mkdir 。 touch 创建的被 linux 认为是 文件,默认初始的文件权限 666):

在这里插入图片描述

(83) 学习一个新命令 umask ,user mask ,设置用户创建的目录与文件的掩码:

在这里插入图片描述

++ 再补充:

在这里插入图片描述

++ 所以函数 mask ( 0 ) 的作用跟命令 mask 是一样的。给予本用户接着要创建的目录和文件,最大的权限,不做任何限制。

(84) 进程 1 建立了文件系统,并打开了三个文件 0 1 2 : 标准输入、标准输出、标准错误。 随后的 fork() ,创建新进程时,复制父进程的控制块 tcb ,也就都默认打开了这三个文件:

在这里插入图片描述

(85) 输入输出重定向:

在这里插入图片描述

(86) 黑洞文件, /dev/null :

在这里插入图片描述

++ /dev/null 被认为是字符设备文件:

在这里插入图片描述

(87) 接着介绍 linux 复制文件句柄的 系统函数 dup() :

在这里插入图片描述

++补充新的系统函数 dup2 ,对应 sys_dup2(),复制文件描述符到指定的句柄:

在这里插入图片描述

++

在这里插入图片描述

++ 补充 close() 函数,待会的实例要用:

在这里插入图片描述

以上得出一个结论:大多数系统调用的函数,正常执行则返回 >=0 的值,出错则统一返回 -1 ,并在全局变量 errno 中记录出错的原因

(88)创建守护进程的范例代码,来自于 nginx 源码:

#include <stdio.h>
#include <stdlib.h>  //malloc
#include <unistd.h>
#include <signal.h>

#include <sys/stat.h>
#include <fcntl.h>

//创建守护进程
//创建成功则返回1,否则返回-1
int ngx_daemon()
{
    int  fd;

    switch (fork())  //fork()子进程
    {
    case -1:
        //创建子进程失败,这里可以写日志......
        return -1;
    case 0:
        //子进程,走到这里,直接break;
        break;
    default:
        //父进程,直接退出 
        exit(0);         
    }

    //只有子进程流程才能走到这里
    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[这是规矩,已经打开的描述符,动他之前,先close],类似于指针指向null,让/dev/null成为标准输入;
    {
        //记录错误日志......
        return -1;
    }

    if (dup2(fd, STDOUT_FILENO) == -1) //先关闭STDIN_FILENO,类似于指针指向null,让/dev/null成为标准输出;
    {
        //记录错误日志......
        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); //休息1秒
            printf("休息1秒,进程id=%d!\n",getpid()); //你就算打印也没用,现在标准输出指向黑洞(/dev/null),打印不出任何结果【不显示任何结果】
        }
    }
    return 0;
}

++ 给出图示:

在这里插入图片描述

++ 给出上述代码的测试结果:

在这里插入图片描述

(89)

谢谢

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值