Chinaunix首页 | 论坛 | 博客
  • 博客访问: 225667
  • 博文数量: 59
  • 博客积分: 1215
  • 博客等级: 少尉
  • 技术积分: 575
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-09 02:18
文章分类

全部博文(59)

文章存档

2012年(53)

2011年(6)

分类: C/C++

2012-03-01 01:42:09

这次来看worker子进程。

ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL,
                          "worker process", type);

 

在创建子进程的同时,注册了一个子进程要执行的函数:ngx_worker_process_cycle。

下面来看这个函数:

  1. static void
  2. ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
  3. {
  4.     ngx_uint_t i;
  5.     ngx_connection_t *c;

  6.     ngx_process = NGX_PROCESS_WORKER;

  7.     ngx_worker_process_init(cycle, 1);

  8.     ngx_setproctitle("worker process");

  9. #if (NGX_THREADS)
  10.     {
  11.     ngx_int_t n;
  12.     ngx_err_t err;
  13.     ngx_core_conf_t *ccf;

  14.     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

  15.     if (ngx_threads_n) {
  16.         if (ngx_init_threads(ngx_threads_n, ccf->thread_stack_size, cycle)
  17.             == NGX_ERROR)
  18.         {
  19.             /* fatal */
  20.             exit(2);
  21.         }

  22.         err = ngx_thread_key_create(&ngx_core_tls_key);
  23.         if (err != 0) {
  24.             ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
  25.                           ngx_thread_key_create_n " failed");
  26.             /* fatal */
  27.             exit(2);
  28.         }

  29.         for (n = 0; n < ngx_threads_n; n++) {

  30.             ngx_threads[n].cv = ngx_cond_init(cycle->log);

  31.             if (ngx_threads[n].cv == NULL) {
  32.                 /* fatal */
  33.                 exit(2);
  34.             }

  35.             if (ngx_create_thread((ngx_tid_t *) &ngx_threads[n].tid,
  36.                                   ngx_worker_thread_cycle,
  37.                                   (void *) &ngx_threads[n], cycle->log)
  38.                 != 0)
  39.             {
  40.                 /* fatal */
  41.                 exit(2);
  42.             }
  43.         }
  44.     }
  45.     }
  46. #endif

  47.     for ( ;; ) {

  48.         if (ngx_exiting) {

  49.             c = cycle->connections;

  50.             for (i = 0; i < cycle->connection_n; i++) {

  51.                 /* THREAD: lock */

  52.                 if (c[i].fd != -1 && c[i].idle) {
  53.                     c[i].close = 1;
  54.                     c[i].read->handler(c[i].read);
  55.                 }
  56.             }

  57.             if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel)
  58.             {
  59.                 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");

  60.                 ngx_worker_process_exit(cycle);
  61.             }
  62.         }

  63.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");

  64.         ngx_process_events_and_timers(cycle);

  65.         if (ngx_terminate) {
  66.             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");

  67.             ngx_worker_process_exit(cycle);
  68.         }

  69.         if (ngx_quit) {
  70.             ngx_quit = 0;
  71.             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
  72.                           "gracefully shutting down");
  73.             ngx_setproctitle("worker process is shutting down");

  74.             if (!ngx_exiting) {
  75.                 ngx_close_listening_sockets(cycle);
  76.                 ngx_exiting = 1;
  77.             }
  78.         }

  79.         if (ngx_reopen) {
  80.             ngx_reopen = 0;
  81.             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
  82.             ngx_reopen_files(cycle, -1);
  83.         }
  84.     }
  85. }

(1)函数首先执行了一个ngx_worker_process_init。这里不进去看了,说说大概的作用:设好进程环境,屏蔽一些信号,还有设好跟其他进程的通信(上次提到过的Unix域用于进程间通信)等等。

(2)接下来涉及线程:首先初始化线程属性、创建“线程标识号”(key)、每一个线程的pthread_cond_t的初始化、创建线程。线程执行的是ngx_worker_thread_cycle这个操作,我们来看看:

  1. static ngx_thread_value_t
  2. ngx_worker_thread_cycle(void *data)
  3. {
  4.     ngx_thread_t *thr = data;

  5.     sigset_t set;
  6.     ngx_err_t err;
  7.     ngx_core_tls_t *tls;
  8.     ngx_cycle_t *cycle;

  9.     cycle = (ngx_cycle_t *) ngx_cycle;

  10.     sigemptyset(&set);
  11.     sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
  12.     sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
  13.     sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));

  14.     err = ngx_thread_sigmask(SIG_BLOCK, &set, NULL);
  15.     if (err) {
  16.         ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
  17.                       ngx_thread_sigmask_n " failed");
  18.         return (ngx_thread_value_t) 1;
  19.     }

  20.     ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
  21.                    "thread " NGX_TID_T_FMT " started", ngx_thread_self());

  22.     ngx_setthrtitle("worker thread");

  23.     tls = ngx_calloc(sizeof(ngx_core_tls_t), cycle->log);
  24.     if (tls == NULL) {
  25.         return (ngx_thread_value_t) 1;
  26.     }

  27.     err = ngx_thread_set_tls(ngx_core_tls_key, tls);
  28.     if (err != 0) {
  29.         ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
  30.                       ngx_thread_set_tls_n " failed");
  31.         return (ngx_thread_value_t) 1;
  32.     }

  33.     ngx_mutex_lock(ngx_posted_events_mutex);

  34.     for ( ;; ) {
  35.         thr->state = NGX_THREAD_FREE;

  36.         if (ngx_cond_wait(thr->cv, ngx_posted_events_mutex) == NGX_ERROR) {
  37.             return (ngx_thread_value_t) 1;
  38.         }

  39.         if (ngx_terminate) {
  40.             thr->state = NGX_THREAD_EXIT;

  41.             ngx_mutex_unlock(ngx_posted_events_mutex);

  42.             ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
  43.                            "thread " NGX_TID_T_FMT " is done",
  44.                            ngx_thread_self());

  45.             return (ngx_thread_value_t) 0;
  46.         }

  47.         thr->state = NGX_THREAD_BUSY;

  48.         if (ngx_event_thread_process_posted(cycle) == NGX_ERROR) {
  49.             return (ngx_thread_value_t) 1;
  50.         }

  51.         if (ngx_event_thread_process_posted(cycle) == NGX_ERROR) {
  52.             return (ngx_thread_value_t) 1;
  53.         }

  54.         if (ngx_process_changes) {
  55.             if (ngx_process_changes(cycle, 1) == NGX_ERROR) {
  56.                 return (ngx_thread_value_t) 1;
  57.             }
  58.         }
  59.     }
  60. }

这个函数的流程大概为:首先是屏蔽一些信号,接着上一个关于有没有事件的锁,接着进入一个for死循环,进入之后线程为free状态,等待事件到来也就是事件锁被打开,最后由ngx_event_thread_process_posted处理被post的事件(估计有一个全局的事件链表,暂未考证,待下面分析再看回来),注意每个线程每一次得到事件锁后处理两个事件。

(3)最后进程(其实应该是主线程,创建的线程都在忙着上面的事)进入死循环,等待一些事情的发生。

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