nginx代码学习_第一章守护进程

7 篇文章 0 订阅
1 篇文章 0 订阅

最近在学习linux的一些开源代码,nginx是我想要学习的第一个目标,因为它十分小巧相对于它的强大功能来说.

我使用过http服务端,文件目录浏览.除此之外我知道的还有反向代理,负载均衡,等功能.最主要的还是他代码量比较少,和我以前使用的项目结构相似有着一定的亲切感.

我主要想了解的几个主要功能模块包括:内存池,守护进程变化,以及http业务解析等,今天先看到了守护进程的代码比较少,先来了解这块代码.

二话不说上代码

ngx_int_t ngx_daemon(ngx_log_t *log)
{
    int  fd;

    switch (fork()) {
    case -1:
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed");
        return NGX_ERROR;

    case 0:          //子进程作为守护进程
        break;

    default:
        exit(0);  //父进程退出
    }

    ngx_pid = ngx_getpid();

    if (setsid() == -1) {   //setsid创建一个新会话
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed");
        return NGX_ERROR;
    }

    umask(0);

    //打开文件/dev/null,使得其拥有守护进程的0,1,2。这样防止守护进程在终端设备上显示输出
    fd = open("/dev/null", O_RDWR);
    if (fd == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                      "open(\"/dev/null\") failed");
        return NGX_ERROR;
    }

    if (dup2(fd, STDIN_FILENO) == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed");
        return NGX_ERROR;
    }

    if (dup2(fd, STDOUT_FILENO) == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed");
        return NGX_ERROR;
    }

#if 0
    if (dup2(fd, STDERR_FILENO) == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed");
        return NGX_ERROR;
    }
#endif

    if (fd > STDERR_FILENO) {
        if (close(fd) == -1) {  //关闭不需要的文件描述符
            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed");
            return NGX_ERROR;
        }
    }

    return NGX_OK;
}

在这段代码里面一开始的frok函数很好理解,创建子进程将会作为守护进程使用,接下里是使用一个switch进行父进程退出.使子进程成为孤儿进程,接着子进程调用setsid创建新的会话,保证在登录会话断掉之后,进程能够一直存在.
在这块有个细节,就是如果是以库的形式提供这个函数的话,为了保险起见一般来说会去frok两次.原因是因为作为库函数的代码不知道接下来的代码会不会有ioctl(TIOCSCTTY)这种调用,如果有的话那么子进程就有当前的session,这时候调用setsid()是不会成功的,所以说这时候就算创建守护进程失败了,但是由于是编写的一整个程序,所以不会有上面之类的调用.

接下来脱离原进程文件权限使用umask,进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除.

然后将三个默认fd重定向到/dev/null上,分别为标准输入,标准输出,错误输出.

这样nginx的守护进程就写完了.但是这个不完全是一个完整的daemon的写法,一个完整的daemon的写法里面还会包括chdir('/'),切换工作目录,防止卸载.


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值