//根据thread_pool name threads=number [max_queue=number];中的number来创建这么多个线程
static ngx_int_t
ngx_thread_pool_init(ngx_thread_pool_t *tp, ngx_log_t *log, ngx_pool_t *pool)
{
    int             err;
    pthread_t       tid;
    ngx_uint_t      n;
    pthread_attr_t  attr;

    if (ngx_notify == NULL) {
        ngx_log_error(NGX_LOG_ALERT, log, 0,
               "the configured event method cannot be used with thread pools");
        return NGX_ERROR;
    }

    ngx_thread_pool_queue_init(&tp->queue);

    if (ngx_thread_mutex_create(&tp->mtx, log) != NGX_OK) {
        return NGX_ERROR;
    }

    if (ngx_thread_cond_create(&tp->cond, log) != NGX_OK) {
        (void) ngx_thread_mutex_destroy(&tp->mtx, log);
        return NGX_ERROR;
    }

    tp->log = log;

    err = pthread_attr_init(&attr);
    if (err) {
        ngx_log_error(NGX_LOG_ALERT, log, err,
                      "pthread_attr_init() failed");
        return NGX_ERROR;
    }

#if 0
    err = pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN);
    if (err) {
        ngx_log_error(NGX_LOG_ALERT, log, err,
                      "pthread_attr_setstacksize() failed");
        return NGX_ERROR;
    }
#endif

    for (n = 0; n < tp->threads; n++) {
        /*
        线程原语:pthread_create(),pthread_self(),pthread_exit(),pthread_join(),pthread_cancel(),pthread_detach( .
        好的线程理解大全参考(有图解例子,很好):http://blog.csdn.net/tototuzuoquan/article/details/39553427
         */
        err = pthread_create(&tid, &attr, ngx_thread_pool_cycle, tp);
        if (err) {
            ngx_log_error(NGX_LOG_ALERT, log, err,
                          "pthread_create() failed");
            return NGX_ERROR;
        }
    }

    (void) pthread_attr_destroy(&attr);

    return NGX_OK;
}
static ngx_int_t
ngx_thread_pool_init(ngx_thread_pool_t *tp, ngx_log_t *log, ngx_pool_t *pool)
{
    int             err;
    pthread_t       tid;
    ngx_uint_t      n;
    pthread_attr_t  attr;
    if (ngx_notify == NULL)
    {
        ngx_log_error(NGX_LOG_ALERT, log, 0,
                      "the configured event method cannot be used with thread pools");
        return NGX_ERROR;
    }
    ngx_thread_pool_queue_init(&tp->queue);
    if (ngx_thread_mutex_create(&tp->mtx, log) != NGX_OK)
    {
        return NGX_ERROR;
    }
    if (ngx_thread_cond_create(&tp->cond, log) != NGX_OK)
    {
        (void) ngx_thread_mutex_destroy(&tp->mtx, log);
        return NGX_ERROR;
    }
    tp->log = log;
    err = pthread_attr_init(&attr);
    if (err)
    {
        ngx_log_error(NGX_LOG_ALERT, log, err,
                      "pthread_attr_init() failed");
        return NGX_ERROR;
    }
#if 0
    err = pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN);
    if (err)
    {
        ngx_log_error(NGX_LOG_ALERT, log, err,
                      "pthread_attr_setstacksize() failed");
        return NGX_ERROR;
    }
#endif
    for (n = 0; n < tp->threads; n++)
    {
        err = pthread_create(&tid, &attr, ngx_thread_pool_cycle, tp);
        if (err)
        {
            ngx_log_error(NGX_LOG_ALERT, log, err,
                          "pthread_create() failed");
            return NGX_ERROR;
        }
    }
    (void) pthread_attr_destroy(&attr);
    return NGX_OK;
}