// 在nginx.c的main()调用 // 初始化ngx_os_io结构体,设置基本的收发函数 // 基本的页大小,ngx_pagesize = getpagesize() // 初始化随机数 // 实际工作在ngx_linux_init.c的ngx_os_specific_init()完成 // 关键操作ngx_os_io = ngx_linux_io;设置为linux的接口函数 ngx_int_t ngx_os_init(ngx_log_t *log) { ngx_uint_t n; #if (NGX_HAVE_OS_SPECIFIC_INIT) // in ngx_linux_init.c // 初始化ngx_os_io结构体,设置为linux的收发函数 if (ngx_os_specific_init(log) != NGX_OK) { return NGX_ERROR; } #endif if (ngx_init_setproctitle(log) != NGX_OK) { return NGX_ERROR; } // 基本的页大小,ngx_pagesize = getpagesize() ngx_pagesize = getpagesize(); // 宏定义为64 // 然后由ngx_cpuinfo(ngx_cpuinfo.c)来探测 ngx_cacheline_size = NGX_CPU_CACHE_LINE; for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ } #if (NGX_HAVE_SC_NPROCESSORS_ONLN) if (ngx_ncpu == 0) { ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN); } #endif if (ngx_ncpu < 1) { ngx_ncpu = 1; } ngx_cpuinfo(); // 最多描述符数量,ngx_max_sockets if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, log, errno, "getrlimit(RLIMIT_NOFILE) failed"); return NGX_ERROR; } ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur; // 在接受连接时使用accept4调用 #if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4) ngx_inherited_nonblocking = 1; #else ngx_inherited_nonblocking = 0; #endif srandom(ngx_time()); return NGX_OK; }
/* 和操作系统相关的初始化 */ ngx_int_t ngx_os_init(ngx_log_t *log) { ngx_uint_t n; #if (NGX_HAVE_OS_SPECIFIC_INIT) /* 操作系统的特殊初始化,如ngx_os_io等等的初始化 * 注意该函数的具体实现在不同平台上进行./configure时,就在 * Makefile文件中指定了 */ if (ngx_os_specific_init(log) != NGX_OK) { return NGX_ERROR; } #endif if (ngx_init_setproctitle(log) != NGX_OK) { return NGX_ERROR; } ngx_pagesize = getpagesize(); ngx_cacheline_size = NGX_CPU_CACHE_LINE; for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ } #if (NGX_HAVE_SC_NPROCESSORS_ONLN) if (ngx_ncpu == 0) { ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN); } #endif if (ngx_ncpu < 1) { ngx_ncpu = 1; } ngx_cpuinfo(); if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, log, errno, "getrlimit(RLIMIT_NOFILE) failed"); return NGX_ERROR; } ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur; #if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4) ngx_inherited_nonblocking = 1; #else ngx_inherited_nonblocking = 0; #endif srandom(ngx_time()); return NGX_OK; }
ngx_int_t ngx_os_init(ngx_log_t *log) { ngx_time_t *tp; ngx_uint_t n; #if (NGX_HAVE_OS_SPECIFIC_INIT) if (ngx_os_specific_init(log) != NGX_OK) { return NGX_ERROR; } #endif if (ngx_init_setproctitle(log) != NGX_OK) { return NGX_ERROR; } ngx_pagesize = getpagesize(); ngx_cacheline_size = NGX_CPU_CACHE_LINE; for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ } #if (NGX_HAVE_SC_NPROCESSORS_ONLN) if (ngx_ncpu == 0) { ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN); } #endif if (ngx_ncpu < 1) { ngx_ncpu = 1; } ngx_cpuinfo(); if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, log, errno, "getrlimit(RLIMIT_NOFILE) failed"); return NGX_ERROR; } ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur; #if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4) ngx_inherited_nonblocking = 1; #else ngx_inherited_nonblocking = 0; #endif tp = ngx_timeofday(); srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec); return NGX_OK; }
ngx_int_t ngx_os_init(ngx_log_t *log) { ngx_uint_t n; #if (NGX_HAVE_OS_SPECIFIC_INIT) // 获取系统信息 if (ngx_os_specific_init(log) != NGX_OK) { return NGX_ERROR; } #endif ngx_init_setproctitle(log); // 获取当前系统的页面大小 ngx_pagesize = getpagesize(); ngx_cacheline_size = NGX_CPU_CACHE_LINE; for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ } #if (NGX_HAVE_SC_NPROCESSORS_ONLN) if (ngx_ncpu == 0) { // 获取CPU数目 ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN); } #endif if (ngx_ncpu < 1) { ngx_ncpu = 1; } // 获取ngx_cacheline_size大小 ngx_cpuinfo(); if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, log, errno, "getrlimit(RLIMIT_NOFILE) failed)"); return NGX_ERROR; } // 获取socket句柄的最大数量限制 ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur; #if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4) ngx_inherited_nonblocking = 1; #else ngx_inherited_nonblocking = 0; #endif // 把时间作为随机数种子 srandom(ngx_time()); return NGX_OK; }
ngx_int_t ngx_os_init(ngx_log_t *log) { ngx_uint_t n; #if (NGX_HAVE_OS_SPECIFIC_INIT) if (ngx_os_specific_init(log) != NGX_OK) { //获取系统版本等信息 return NGX_ERROR; } #endif if (ngx_init_setproctitle(log) != NGX_OK) { //保存环境变量,跟设置进程名有关 return NGX_ERROR; } ngx_pagesize = getpagesize(); //获取系统内粗pagesize ngx_cacheline_size = NGX_CPU_CACHE_LINE; //获取cacheline size for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ } #if (NGX_HAVE_SC_NPROCESSORS_ONLN) if (ngx_ncpu == 0) { ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);//获取CPU核数 } #endif if (ngx_ncpu < 1) { ngx_ncpu = 1; } ngx_cpuinfo(); //获取CPU类型,根据CPU类型设置ngx_cacheline_size if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, log, errno, "getrlimit(RLIMIT_NOFILE) failed)"); return NGX_ERROR; } ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur; //获取当前系统设置每个进程能打开文件的个数 #if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4) ngx_inherited_nonblocking = 1; #else ngx_inherited_nonblocking = 0; #endif srandom(ngx_time()); //初始化随机数 return NGX_OK; }
/* 初始化系统相关变量,如内存页面大小ngx_pagesize,ngx_cacheline_size, 最大连接数ngx_max_sockets等 */ ngx_int_t ngx_os_init(ngx_log_t *log) { ngx_uint_t n; #if (NGX_HAVE_OS_SPECIFIC_INIT) if (ngx_os_specific_init(log) != NGX_OK) { return NGX_ERROR; } #endif ngx_init_setproctitle(log); /** 该函数为glibc的库函数,由系统调用实现,返回内核中的PAGE_SIZE,该值依赖体系结构*/ ngx_pagesize = getpagesize(); ngx_cacheline_size = NGX_CPU_CACHE_LINE; for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ } #if (NGX_HAVE_SC_NPROCESSORS_ONLN) if (ngx_ncpu == 0) { ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN); } #endif if (ngx_ncpu < 1) { ngx_ncpu = 1; } ngx_cpuinfo(); if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, log, errno, "getrlimit(RLIMIT_NOFILE) failed)"); return NGX_ERROR; } ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur; #if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4) ngx_inherited_nonblocking = 1; #else ngx_inherited_nonblocking = 0; #endif srandom(ngx_time()); return NGX_OK; }
ngx_int_t ngx_os_init(ngx_log_t *log) { ngx_uint_t n; #if (NGX_HAVE_OS_SPECIFIC_INIT) if (ngx_os_specific_init(log) != NGX_OK) { return NGX_ERROR; } #endif ngx_init_setproctitle(log); ngx_pagesize = getpagesize(); ngx_cacheline_size = NGX_CPU_CACHE_LINE; n = ngx_pagesize; for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ } if (ngx_ncpu == 0) { ngx_ncpu = 1; } ngx_cpuinfo(); if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, log, errno, "getrlimit(RLIMIT_NOFILE) failed)"); return NGX_ERROR; } ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur; #if (NGX_HAVE_INHERITED_NONBLOCK) ngx_inherited_nonblocking = 1; #else ngx_inherited_nonblocking = 0; #endif srandom(ngx_time()); return NGX_OK; }
/** * @param [in] log 日志对象 * @return int NGX_OK|NGX_ERROR * * 初始化系统相关变量 * 如内存页面大小ngx_pagesize ngx_cacheline_size ngx_max_sockets等 * * \file ngx_os.h 申明原型 */ ngx_int_t ngx_os_init(ngx_log_t *log) { ngx_uint_t n; #if (NGX_HAVE_OS_SPECIFIC_INIT) /** * \file ngx_linux_init.c * OS指定的初始化:初始化内核名称和其它信息,设置全局变量ngx_os_io,后续用于I/O操作基础(包括网络I/O) */ if (ngx_os_specific_init(log) != NGX_OK) { return NGX_ERROR; } #endif /** * \file ngx_setproctitle.h|c * 移动**environ到堆上,为设置进程标题做准备 */ if (ngx_init_setproctitle(log) != NGX_OK) { return NGX_ERROR; } /** * \file ngx_alloc.h|c * os页大小 x86为4096 */ ngx_pagesize = getpagesize(); //os页大小 x86为4096 /** * \file ../../../objs/ngx_auto_config.h * #define NGX_CPU_CACHE_LINE 64 * 主要用于内存池对齐分配。即本机cpu的cache line为64,内存池起始地址也要是64的倍数 */ ngx_cacheline_size = NGX_CPU_CACHE_LINE; //slab用到,计算要多少个cache line填满一页 2^12=4096 ngx_pagesize_shift=12 for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ } #if (NGX_HAVE_SC_NPROCESSORS_ONLN) if (ngx_ncpu == 0) { ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN); //cpu实际个数,配置文件worker_processes } #endif if (ngx_ncpu < 1) { ngx_ncpu = 1; } /** * \file ../../core/cpuinfo.c * 调用汇编代码,获取cpu信息,主要用于根据实际cpu信息设置ngx_cacheline_size的值 */ ngx_cpuinfo(); if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { //进程可打开最大文件描述符上限 ngx_log_error(NGX_LOG_ALERT, log, errno, "getrlimit(RLIMIT_NOFILE) failed"); return NGX_ERROR; } ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur; //打开socket描述符最大数量 //socket是否可阻塞设置开关 #if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4) ngx_inherited_nonblocking = 1; #else ngx_inherited_nonblocking = 0; //TODO 我的系统为0? #endif srandom(ngx_time()); //设置random函数的种子 return NGX_OK; }