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

来源:互联网 发布:淘宝开店怎么描述店铺 编辑:程序博客网 时间:2024/05/16 06:13

最近在学习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
原创粉丝点击