nginx pthread mutex and condtion signal

本文介绍了Nginx中线程管理的相关实现细节,包括线程的创建、销毁、同步等核心功能。针对不同的操作系统环境,Nginx提供了灵活的线程管理方案,并通过条件变量和互斥锁来确保线程间的正确同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



/*
 * Copyright (C) Igor Sysoev
 */




#ifndef _NGX_THREAD_H_INCLUDED_
#define _NGX_THREAD_H_INCLUDED_




#include <ngx_config.h>
#include <ngx_core.h>


#if (NGX_THREADS)


#define NGX_MAX_THREADS      128


#if (NGX_USE_RFORK)
#include <ngx_freebsd_rfork_thread.h>




#else /* use pthreads */


#include <pthread.h>


typedef pthread_t                    ngx_tid_t;


#define ngx_thread_self()            pthread_self()
#define ngx_log_tid                  (int) ngx_thread_self()


#if (NGX_FREEBSD) && !(NGX_LINUXTHREADS)
#define NGX_TID_T_FMT                "%p"
#else
#define NGX_TID_T_FMT                "%d"
#endif




typedef pthread_key_t                ngx_tls_key_t;


#define ngx_thread_key_create(key)   pthread_key_create(key, NULL)
#define ngx_thread_key_create_n      "pthread_key_create()"
#define ngx_thread_set_tls           pthread_setspecific
#define ngx_thread_set_tls_n         "pthread_setspecific()"
#define ngx_thread_get_tls           pthread_getspecific




#define NGX_MUTEX_LIGHT     0


typedef struct {
    pthread_mutex_t   mutex;
    ngx_log_t        *log;
} ngx_mutex_t;


typedef struct {
    pthread_cond_t    cond;
    ngx_log_t        *log;
} ngx_cond_t;


#define ngx_thread_sigmask     pthread_sigmask
#define ngx_thread_sigmask_n  "pthread_sigmask()"


#define ngx_thread_join(t, p)  pthread_join(t, p)


#define ngx_setthrtitle(n)






ngx_int_t ngx_mutex_trylock(ngx_mutex_t *m);
void ngx_mutex_lock(ngx_mutex_t *m);
void ngx_mutex_unlock(ngx_mutex_t *m);


#endif




#define ngx_thread_volatile   volatile




typedef struct {
    ngx_tid_t    tid;
    ngx_cond_t  *cv;
    ngx_uint_t   state;
} ngx_thread_t;


#define NGX_THREAD_FREE   1
#define NGX_THREAD_BUSY   2
#define NGX_THREAD_EXIT   3
#define NGX_THREAD_DONE   4


extern ngx_int_t              ngx_threads_n;
extern volatile ngx_thread_t  ngx_threads[NGX_MAX_THREADS];




typedef void *  ngx_thread_value_t;


ngx_int_t ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle);
ngx_err_t ngx_create_thread(ngx_tid_t *tid,
    ngx_thread_value_t (*func)(void *arg), void *arg, ngx_log_t *log);


ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags);
void ngx_mutex_destroy(ngx_mutex_t *m);




ngx_cond_t *ngx_cond_init(ngx_log_t *log);
void ngx_cond_destroy(ngx_cond_t *cv);
ngx_int_t ngx_cond_wait(ngx_cond_t *cv, ngx_mutex_t *m);
ngx_int_t ngx_cond_signal(ngx_cond_t *cv);




#else /* !NGX_THREADS */


#define ngx_thread_volatile


#define ngx_log_tid           0
#define NGX_TID_T_FMT         "%d"


#define ngx_mutex_trylock(m)  NGX_OK
#define ngx_mutex_lock(m)
#define ngx_mutex_unlock(m)


#define ngx_cond_signal(cv)


#define ngx_thread_main()     1


#endif




#endif /* _NGX_THREAD_H_INCLUDED_ */




/*
 * Copyright (C) Igor Sysoev
 */




#include <ngx_config.h>
#include <ngx_core.h>




static ngx_uint_t   nthreads;
static ngx_uint_t   max_threads;




static pthread_attr_t  thr_attr;




ngx_err_t
ngx_create_thread( ngx_tid_t *tid,   ngx_thread_value_t (*func)( void *arg ),
    void *arg, ngx_log_t *log )
{
    int  err;


    if ( nthreads >= max_threads ) 
{
        ngx_log_error( NGX_LOG_CRIT, log, 0,
                      "no more than %ui threads can be created", max_threads );


        return NGX_ERROR;
    }


    err = pthread_create( tid, &thr_attr, func, arg );


    if ( err != 0 ) 
{
        ngx_log_error( NGX_LOG_ALERT, log, err, "pthread_create() failed" );


        return err;
    }


    ngx_log_debug1( NGX_LOG_DEBUG_CORE, log, 0,
                   "thread is created: " NGX_TID_T_FMT, *tid );


    nthreads++; // 全局变量nthreads记录了创建的线程总数


    return err;
}


//初始化全局变量thr_attr,设置栈的大小为参数size


ngx_int_t
ngx_init_threads( int n, size_t size, ngx_cycle_t *cycle )
{
    int  err;


    max_threads = n;


    err = pthread_attr_init( &thr_attr );


    if ( err != 0 ) 
{
        ngx_log_error( NGX_LOG_ALERT, cycle->log, err,
                      "pthread_attr_init() failed" );


        return NGX_ERROR;
    }


    err = pthread_attr_setstacksize( &thr_attr, size );


    if ( err != 0 )
{
        ngx_log_error( NGX_LOG_ALERT, cycle->log, err,
                      "pthread_attr_setstacksize() failed" );
        return NGX_ERROR;
    }


    ngx_threaded = 1; //设置为1表示已经初始化线程属性初始化好了


    return NGX_OK;
}


//分配空间,初始化一个线程锁


ngx_mutex_t *
ngx_mutex_init( ngx_log_t *log, ngx_uint_t flags )
{
    int           err;
    ngx_mutex_t  *m;


    m = ngx_alloc( sizeof ( ngx_mutex_t ), log );


    if ( m == NULL ) 
{
        return NULL;
    }


    m->log = log;


    err = pthread_mutex_init( &m->mutex, NULL );


    if ( err != 0 ) 
{
        ngx_log_error( NGX_LOG_ALERT, m->log, err,
                      "pthread_mutex_init() failed" );


        return NULL;
    }


    return m;
}


//释放一个线程锁


void
ngx_mutex_destroy( ngx_mutex_t *m )
{
    int  err;


    err = pthread_mutex_destroy( &m->mutex );


    if ( err != 0 )
{
        ngx_log_error( NGX_LOG_ALERT, m->log, err,
                      "pthread_mutex_destroy(%p) failed", m );
    }


    ngx_free(m);
}




//锁住mutex  m


void
ngx_mutex_lock( ngx_mutex_t *m )
{
    int  err;


    if ( !ngx_threaded ) //没有初始化线程属性结构体,则直接返回
{
        return;
    }


    ngx_log_debug1( NGX_LOG_DEBUG_MUTEX, m->log, 0, "lock mutex %p", m );


    err = pthread_mutex_lock( &m->mutex );


    if ( err != 0 ) 
{
        ngx_log_error( NGX_LOG_ALERT, m->log, err,
                      "pthread_mutex_lock(%p) failed", m );


        ngx_abort();
    }


    ngx_log_debug1( NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m );


    return;
}




ngx_int_t
ngx_mutex_trylock( ngx_mutex_t *m )
{
    int  err;


    if ( !ngx_threaded )
{
        return NGX_OK;
    }


    ngx_log_debug1( NGX_LOG_DEBUG_MUTEX, m->log, 0, "try lock mutex %p", m );


    err = pthread_mutex_trylock( &m->mutex );


    if ( err == NGX_EBUSY ) // 锁被别的线程占住了,返回EAGAIN
{
        return NGX_AGAIN;
    }


    if ( err != 0 ) 
{
        ngx_log_error( NGX_LOG_ALERT, m->log, err,
                      "pthread_mutex_trylock(%p) failed", m );


        ngx_abort();
    }


    ngx_log_debug1( NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m );


    return NGX_OK;
}




void
ngx_mutex_unlock( ngx_mutex_t *m )
{
    int  err;


    if ( !ngx_threaded )
{
        return;
    }


    ngx_log_debug1( NGX_LOG_DEBUG_MUTEX, m->log, 0, "unlock mutex %p", m );


    err = pthread_mutex_unlock( &m->mutex );


    if  (err != 0 ) 
{
        ngx_log_error( NGX_LOG_ALERT, m->log, err,
                      "pthread_mutex_unlock(%p) failed", m );


        ngx_abort();
    }


    ngx_log_debug1( NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is unlocked", m );


    return;
}




ngx_cond_t *
ngx_cond_init( ngx_log_t *log )
{
    int          err;


    ngx_cond_t  *cv;


    cv = ngx_alloc( sizeof( ngx_cond_t ), log );


    if ( cv == NULL ) 
{
        return NULL;
    }


    cv->log = log;


    err = pthread_cond_init( &cv->cond, NULL );


    if ( err != 0 )
{
        ngx_log_error( NGX_LOG_ALERT, cv->log, err,
                      "pthread_cond_init() failed" );
        return NULL;
    }


    return cv;
}




void
ngx_cond_destroy( ngx_cond_t *cv )
{
    int  err;


    err = pthread_cond_destroy( &cv->cond );


    if ( err != 0 )
{
        ngx_log_error( NGX_LOG_ALERT, cv->log, err,
                      "pthread_cond_destroy(%p) failed", cv );
    }


    ngx_free( cv );
}




ngx_int_t
ngx_cond_wait( ngx_cond_t *cv, ngx_mutex_t *m )
{
    int  err;


    ngx_log_debug1( NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p wait", cv );


    err = pthread_cond_wait( &cv->cond, &m->mutex );


    if ( err != 0 ) 
{
        ngx_log_error( NGX_LOG_ALERT, cv->log, err,
                      "pthread_cond_wait(%p) failed", cv );


        return NGX_ERROR;
    }


    ngx_log_debug1( NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is waked up", cv );


    ngx_log_debug1( NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m );


    return NGX_OK;
}




ngx_int_t
ngx_cond_signal( ngx_cond_t *cv )
{
    int  err;


    ngx_log_debug1( NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p to signal", cv );


    err = pthread_cond_signal( &cv->cond );


    if ( err != 0 )
{
        ngx_log_error( NGX_LOG_ALERT, cv->log, err,
                      "pthread_cond_signal(%p) failed", cv );


        return NGX_ERROR;
    }


    ngx_log_debug1( NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is signaled", cv );


    return NGX_OK;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值