10.Nginx启动流程之ngx_os_init
来源:互联网 发布:原理电路仿真软件 编辑:程序博客网 时间:2024/06/09 13:18
Nginx在启动流程中会调用ngx_os_init来初始化一些与操作系统有关的全局变量,不同操作系统下ngx_os_init的实现不同,在os/unix下我们看到Nginx为linux、freebsd、solaris等操作系统实现了对应的ngx_os_init函数。下面以linux操作系统进行讲解:
/* os/unix/ngx_posix.c */ngx_int_t ngx_ncpu;ngx_int_t ngx_max_sockets; // 用于记录可持有的最大套接字描述符数量ngx_int_t ngx_inherited_nonblocking;struct rlimit rlmt;void ngx_signal_handler(int signo);typedef struct { int signo; char *signame; void (*handler)(int signo);} ngx_signal_t;ngx_signal_t signals[] = { { ngx_signal_value(NGX_RECONFIGURE_SIGNAL), "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL), ngx_signal_handler }, { ngx_signal_value(NGX_REOPEN_SIGNAL), "SIG" ngx_value(NGX_REOPEN_SIGNAL), ngx_signal_handler }, { ngx_signal_value(NGX_NOACCEPT_SIGNAL), "SIG" ngx_value(NGX_NOACCEPT_SIGNAL), ngx_signal_handler }, { ngx_signal_value(NGX_TERMINATE_SIGNAL), "SIG" ngx_value(NGX_TERMINATE_SIGNAL), ngx_signal_handler }, { ngx_signal_value(NGX_SHUTDOWN_SIGNAL), "SIG" ngx_value(NGX_SHUTDOWN_SIGNAL), ngx_signal_handler }, { ngx_signal_value(NGX_CHANGEBIN_SIGNAL), "SIG" ngx_value(NGX_CHANGEBIN_SIGNAL), ngx_signal_handler }, { SIGALRM, "SIGALRM", ngx_signal_handler }, { SIGINT, "SIGINT", ngx_signal_handler }, { SIGIO, "SIGIO", ngx_signal_handler }, { SIGCHLD, "SIGCHLD", ngx_signal_handler }, { SIGPIPE, "SIGPIPE, SIG_IGN", SIG_IGN }, { 0, NULL, NULL }};/* Posix下进行系统相关初始化工作 */ngx_int_t ngx_posix_init(ngx_log_t *log){ ngx_signal_t *sig; struct sigaction sa; // 调用unistd.h中getpagesize函数来获取内存分页大小, 单位为Byte ngx_pagesize = getpagesize(); // ngx_ncpu简单置为1 if (ngx_ncpu == 0) { ngx_ncpu = 1; } for (sig = signals; sig->signo != 0; sig++) { // 遍历感兴趣的信号列表, 然后依次调用sigaction来为它们设置信号处理函数, // 从上面可见大部分的信号都使用的ngx_signal_handler处理函数, 只有SIGPIPE是SIG_IGN, 也就是忽略此信号 ngx_memzero(&sa, sizeof(struct sigaction)); sa.sa_handler = sig->handler; sigemptyset(&sa.sa_mask); if (sigaction(sig->signo, &sa, NULL) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "sigaction(%s) failed", sig->signame); return NGX_ERROR; } } // 调用getrlimit来获取进程可以打开的最大文件数 // 我们可以使用ulimit -n命令来获取内核的默认值 if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, log, errno, "getrlimit(RLIMIT_NOFILE) failed)"); return NGX_ERROR; } ngx_max_sockets = rlmt.rlim_cur;#if (HAVE_INHERITED_NONBLOCK) ngx_inherited_nonblocking = 1;#else ngx_inherited_nonblocking = 0;#endif return NGX_OK;}/* os/unix/ngx_linux_init.c */char ngx_linux_kern_ostype[50]; // 用于存放操作系统类型的字符数组全局变量char ngx_linux_kern_osrelease[20]; // 用于存放内核版本的字符数组全局变量int ngx_linux_rtsig_max; // /* Linux下进行系统相关初始化工作 */ngx_int_t ngx_os_init(ngx_log_t *log){ int name[2], len; // 调用sysctl来获取操作系统类型 // 我在进行测试时, 如果ngx_linux_kern_ostype作为函数的局部变量, 那么调用会返回-1, // 出错代码errno:14, 也就是"bad address"; 但是全局变量就不会, 很奇怪, 下面的获取内核版本也是这样 name[0] = CTL_KERN; name[1] = KERN_OSTYPE; len = sizeof(ngx_linux_kern_ostype); if (sysctl(name, sizeof(name), ngx_linux_kern_ostype, &len, NULL, 0) == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "sysctl(KERN_OSTYPE) failed"); return NGX_ERROR; } // 调用sysctl来获取内核版本 name[0] = CTL_KERN; name[1] = KERN_OSRELEASE; len = sizeof(ngx_linux_kern_osrelease); if (sysctl(name, sizeof(name), ngx_linux_kern_osrelease, &len, NULL, 0) == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "sysctl(KERN_OSRELEASE) failed"); return NGX_ERROR; } // 调用sysctl来获取最大可排队的实时信号数量 // 在Linux下测试时会报错errno:20, "Not a directory", // 不过这里出错后, 不像上面2个会返回NGX_ERROR, 而是直接置ngx_linux_rtsig_max为0 name[0] = CTL_KERN; name[1] = KERN_RTSIGMAX; len = sizeof(ngx_linux_rtsig_max); if (sysctl(name, sizeof(name), &ngx_linux_rtsig_max, &len, NULL, 0) == -1) { ngx_log_error(NGX_LOG_INFO, log, ngx_errno, "sysctl(KERN_RTSIGMAX) failed"); ngx_linux_rtsig_max = 0; } // 调用Posix下系统相关初始化函数 return ngx_posix_init(log);}
阅读全文
0 0
- 10.Nginx启动流程之ngx_os_init
- nginx启动流程之master进程初始化
- nginx启动流程之work初始化
- 11.Nginx启动流程之ngx_add_inherited_sockets
- 12.Nginx启动流程之ngx_init_cycle
- Nginx学习之十一-Nginx启动框架处理流程
- Nginx学习之十一-Nginx启动框架处理流程
- Nginx学习之十一-Nginx启动框架处理流程
- Nginx学习之十一-Nginx启动框架处理流程
- Nginx启动初始化流程
- 【Nginx】启动流程
- Nginx启动流程
- Nginx启动框架处理流程
- Nginx学习笔记(十三):Nginx启动流程
- Nginx学习(12)—Nginx启动流程
- nginx学习十一 nginx启动流程
- nginx的启动流程和接客流程
- nginx源码分析—启动流程
- idea使用数据库连接工具
- 欢迎使用CSDN-markdown编辑器
- JavaScript核心对象-数组对象
- Linux下history命令用法
- Ubutu git 安装node.js
- 10.Nginx启动流程之ngx_os_init
- Ubuntu Linux更改PATH路径(转)
- python3 writerow CSV文件多一个空行
- 如何用消息系统避免分布式事务?
- Laravel find in set排序
- 安装配置php-fpm来搭建Nginx+PHP的生产环境
- 约瑟夫环的三种实现
- oracle数据库ip地址改变重启机器后连不上数据库解决方法
- Tomcat+Redis cluster