Chinaunix首页 | 论坛 | 博客
  • 博客访问: 562939
  • 博文数量: 142
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1452
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-12 16:28
文章分类

全部博文(142)

文章存档

2016年(10)

2015年(60)

2014年(72)

我的朋友

分类: 服务器与存储

2016-05-16 17:26:41

废话不多说,直接上代码和注释,有问题或者有不足的地方可以大家一起讨论。


点击(此处)折叠或打开

  1. int ngx_cdecl
  2. main(int argc, char *const *argv)
  3. {
  4.     ngx_int_t i;
  5.     ngx_log_t *log;
  6.     ngx_cycle_t *cycle, init_cycle;
  7.     ngx_core_conf_t *ccf;
  8.     /* 在linux为空函数 ,
  9.      * src/os/unix/ngx_linux_config.h
  10.      * #define ngx_debug_init()
  11.      **/
  12.     ngx_debug_init();
  13.     /*将linux系统标准的errno信息strerror字符串存储成一个数组链,数组总的大小由宏NGX_SYS_NERR控制*/
  14.     if (ngx_strerror_init() != NGX_OK) {
  15.         return 1;
  16.     }
  17.     /*对选项参数的解析,此处并没有像一般的linux程序一样调用getopt/getopt_long,
  18.      * 而是通过对选项的字符识别来解析参数,可以解决不同平台兼容问题,如使用windows and linux*/
  19.     if (ngx_get_options(argc, argv) != NGX_OK) {
  20.         return 1;
  21.     }
  22.     /*根据入参选项,来判断是否输出nginx版本,nginx帮助信息,nginx配置信息等等*/
  23.     if (ngx_show_version) {
  24.         ngx_write_stderr("nginx version: " NGINX_VER_BUILD NGX_LINEFEED);/*nginx_write_stderr将信心输出到标准错误文件句柄,直接显示在终端*/

  25.         if (ngx_show_help) {
  26.             ngx_write_stderr(
  27.                 "Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
  28.                              "[-p prefix] [-g directives]" NGX_LINEFEED
  29.                              NGX_LINEFEED
  30.                 "Options:" NGX_LINEFEED
  31.                 " -?,-h : this help" NGX_LINEFEED
  32.                 " -v : show version and exit" NGX_LINEFEED
  33.                 " -V : show version and configure options then exit"
  34.                                    NGX_LINEFEED
  35.                 " -t : test configuration and exit" NGX_LINEFEED
  36.                 " -q : suppress non-error messages "
  37.                                    "during configuration testing" NGX_LINEFEED
  38.                 " -s signal : send signal to a master process: "
  39.                                    "stop, quit, reopen, reload" NGX_LINEFEED
  40. #ifdef NGX_PREFIX
  41.                 " -p prefix : set prefix path (default: "
  42.                                    NGX_PREFIX ")" NGX_LINEFEED
  43. #else
  44.                 " -p prefix : set prefix path (default: NONE)" NGX_LINEFEED
  45. #endif
  46.                 " -c filename : set configuration file (default: "
  47.                                    NGX_CONF_PATH ")" NGX_LINEFEED
  48.                 " -g directives : set global directives out of configuration "
  49.                                    "file" NGX_LINEFEED NGX_LINEFEED
  50.                 );
  51.         }

  52.         if (ngx_show_configure) {

  53. #ifdef NGX_COMPILER
  54.             ngx_write_stderr("built by " NGX_COMPILER NGX_LINEFEED);
  55. #endif

  56. #if (NGX_SSL)
  57.             if (SSLeay() == SSLEAY_VERSION_NUMBER) {
  58.                 ngx_write_stderr("built with " OPENSSL_VERSION_TEXT
  59.                                  NGX_LINEFEED);
  60.             } else {
  61.                 ngx_write_stderr("built with " OPENSSL_VERSION_TEXT
  62.                                  " (running with ");
  63.                 ngx_write_stderr((char *) (uintptr_t)
  64.                                  SSLeay_version(SSLEAY_VERSION));
  65.                 ngx_write_stderr(")" NGX_LINEFEED);
  66.             }
  67. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
  68.             ngx_write_stderr("TLS SNI support enabled" NGX_LINEFEED);
  69. #else
  70.             ngx_write_stderr("TLS SNI support disabled" NGX_LINEFEED);
  71. #endif
  72. #endif

  73.             ngx_write_stderr("configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
  74.         }

  75.         if (!ngx_test_config) {
  76.             return 0;
  77.         }
  78.     }

  79.     /* TODO */ ngx_max_sockets = -1;

  80.     ngx_time_init();/*时间初始化*/
  81. /*如果有PCRE库,则进行正则表达式初始化*/
  82. #if (NGX_PCRE)
  83.     ngx_regex_init();
  84. #endif

  85.     ngx_pid = ngx_getpid();/*获取当前进程id,放入全局变量ngx_pid中*/
  86.     /*将ngx_log.c里面的静态变量ngx_log的地址返回给局部log变量*/
  87.     log = ngx_log_init(ngx_prefix);/*初始化日志文件*/
  88.     if (log == NULL) {
  89.         return 1;
  90.     }

  91.     /* STUB */
  92. #if (NGX_OPENSSL)
  93.     ngx_ssl_init(log);
  94. #endif

  95.     /*
  96.      * init_cycle->log is required for signal handlers and
  97.      * ngx_process_options()
  98.      */
  99.     /*初始化ngx_cycle_t结构变量init_cycle*/
  100.     ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
  101.     init_cycle.log = log;/*将log指针赋值给init_cycle结构中的log*/
  102.     ngx_cycle = &init_cycle;/*ngx_cycle指针指向init_cycle的地址*/
  103.     /*创建内存地址池::::TODO,后面详细学习分析*/
  104.     init_cycle.pool = ngx_create_pool(1024, log);
  105.     if (init_cycle.pool == NULL) {
  106.         return 1;
  107.     }
  108.     /*将命令参数和环境变量保存到ngx_os_argv,ngx_argc,ngx_argv和ngx_os_environ中,
  109.      * 这个是一个备份存储,方便后面的初始化工作能够随时获取命令行参数*/
  110.     if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
  111.         return 1;
  112.     }
  113.     /*nginx前缀,配置文件前缀和配置文件路径等写入init_cycle结构*/
  114.     if (ngx_process_options(&init_cycle) != NGX_OK) {
  115.         return 1;
  116.     }
  117.     /*完成操作系统的一些信息获取,比如内存页面大小、系统限制资源等信息;
  118.      * 所有这些资源都保存到对应的全局变量中,以便后续访问*/
  119.     if (ngx_os_init(log) != NGX_OK) {
  120.         return 1;
  121.     }

  122.     /*
  123.      * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
  124.      */
  125.     /*初始化CRC表,以便后续CRC校验通过查表进行,效率高*/
  126.     if (ngx_crc32_table_init() != NGX_OK) {
  127.         return 1;
  128.     }
  129.     /*解析环境变量NGINX_VAR="NGINX"中的sockets,并保存至ngx_cycle.listening数组中*/
  130.     if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
  131.         return 1;
  132.     }
  133.     /*统计模块总数,并且记录模块索引*/
  134.     ngx_max_module = 0;
  135.     for (i = 0; ngx_modules[i]; i++) {
  136.         ngx_modules[i]->index = ngx_max_module++;
  137.     }
  138.     /*cycle是周期的意思,对应着一次启动过程,每次启动,nginx都会创建一个新的cycle与这次启动对应
  139.      * 初始化cycle,入参init_cycle为老的cycle,主要存储了log和配置文件相关的信息,还有main函数入参信息
  140.      * ngx_init_cycle函数的主要作用:
  141.      * 1. 解析nginx配置文件
  142.      * 2. 初始化core模块
  143.      * 3. 初始化文件句柄
  144.      * 4. 初始化共享内存
  145.      * 5. 监听端口*/
  146.     cycle = ngx_init_cycle(&init_cycle);
  147.     if (cycle == NULL) {
  148.         if (ngx_test_config) {
  149.             ngx_log_stderr(0, "configuration file %s test failed",
  150.                            init_cycle.conf_file.data);
  151.         }

  152.         return 1;
  153.     }

  154.     if (ngx_test_config) {
  155.         if (!ngx_quiet_mode) {
  156.             ngx_log_stderr(0, "configuration file %s test is successful",
  157.                            cycle->conf_file.data);
  158.         }

  159.         return 0;
  160.     }
  161.     /*nginx -s 信号选项,处理相应的信号选项,根据信号类型,调用kill向自身发送信号*/
  162.     if (ngx_signal) {
  163.         return ngx_signal_process(cycle, ngx_signal);
  164.     }

  165.     ngx_os_status(cycle->log);

  166.     ngx_cycle = cycle;

  167.     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
  168.     ngx_log_error(NGX_LOG_DEBUG,log,0,"master=%z",ccf->master);
  169.     /*ccf->master值在core模块conf init函数中已经初始化为1*/
  170.     if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
  171.         ngx_process = NGX_PROCESS_MASTER;
  172.     }

  173. #if !(NGX_WIN32)
  174.     /*初始化信号,注册信号处理函数
  175.      * 需要注册的信号及相应的信号处理函数被放在一个类型为ngx_signal_t的数组signals中。
  176.      * 数组定义在src/os/unix/ngx_process.c中。ngx_signal_t结构类型定义了信号值,信号名字,信号对应动作名以及信号处理函数。
  177.      * */
  178.     if (ngx_init_signals(cycle->log) != NGX_OK) {
  179.         return 1;
  180.     }
  181.     /*设置为daemon进程*/
  182.     if (!ngx_inherited && ccf->daemon) {
  183.         if (ngx_daemon(cycle->log) != NGX_OK) {
  184.             return 1;
  185.         }

  186.         ngx_daemonized = 1;
  187.     }

  188.     if (ngx_inherited) {
  189.         ngx_daemonized = 1;
  190.     }

  191. #endif
  192.     /* 把进程id记入到文件中
  193.      * 如果配置文件nginx.conf里面没有配置 pid logs/nginx.pid;
  194.      * 则在core模块初始化配置ngx_core_module_init_conf时设置ccf->pid为默认路径
  195.      * "/usr/local/nginx/nginx.pid"*/
  196.     if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
  197.         return 1;
  198.     }
  199.     /*调用dup2将标准错误复制为log 文件句柄,
  200.      * 即后续往标准错误里面写入的东西,都会体现在log文件句柄中
  201.      * fd = ngx_log_get_file_log(cycle->log)->file->fd*/
  202.     if (ngx_log_redirect_stderr(cycle) != NGX_OK) {
  203.         return 1;
  204.     }

  205.     if (log->file->fd != ngx_stderr) {
  206.         if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
  207.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
  208.                           ngx_close_file_n " built-in log failed");
  209.         }
  210.     }

  211.     ngx_use_stderr = 0;
  212.     ngx_log_stderr(0,"ngx_process = %d",ngx_process);
  213.     /*Nginx分为Single和Master两种进程模型,Single模型即为单进程方式工作,具有较差的容错能力,不适合生产之用。
  214.      * Master模型即为一个master进程+N个worker进程的工作方式。*/
  215.     if (ngx_process == NGX_PROCESS_SINGLE) {
  216.         ngx_single_process_cycle(cycle);

  217.     } else {
  218.         ngx_master_process_cycle(cycle);
  219.     }

  220.     return 0;
  221. }

阅读(1188) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~