nginx源代码分析 - 启动(八) 避免epoll_wait惊群

nginx使用epoll来处理accept事件,所有会有epoll惊群问题,


ngx_accept_disabled = ngx_cycle->connection_n / 8 - ngx_cycle->free_connection_n; 这个变量是禁用accept,就是现在的连接数比较多
ngx_use_accept_mutex全局变量为1,才开启避免惊群的现象

ngx_use_accept_mutex = 1;的条件是ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex
对应的配置是在event block下面accept_mutex on;

在ngx_event_process_init函数中如果ngx_use_accept_mutex开启,则不会将fd加入本worker进程的epoll
在worker进程的大循环,ngx_process_events_and_timers函数在,如果ngx_use_accept_mutex开启,则所有进程都会去得到ngx_accept_mutex
得到的把listen的fd加到本进程的epoll中,其他的都移除。

这个锁是放在共享内存上的
cl = 128;/* cl should be equal to or greater than cache line size */
size = cl            /* ngx_accept_mutex */
           + cl          /* ngx_connection_counter */
           + cl;         /* ngx_temp_number */

NGX_HAVE_MAP_ANON
shm->addr = (u_char *) mmap(NULL, shm->size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

全局变量ngx_accept_mutex_ptr保存了这一地址,这是个内核地址,所有进程都可以访问,也就成共享内存了
ngx_shmtx_sh_t只有16字节,却分配了128字节
全局变量ngx_accept_mutex->lock = &addr->lock
全局变量是指每个进程的,但是每个进程的这个变量都指向内核同一地址
(gdb) p  ngx_accept_mutex->lock
$1 = (ngx_atomic_t *) 0x7ffff7ff5000
(gdb) p  *ngx_accept_mutex->lock
$2 = 0

(void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1); 设置ngx_connection_counter = 1
           
锁的名字/home/liuwb/Desktop/code/nginx-code/logs/nginx.lock.accept
*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid) 如果mtx->lock == 0,将mtx->lock的值设为ngx_pid,返回1
将ngx_pid的值设在mtx->lock中,是这个worker的pid

ngx_accept_events = 0;
ngx_accept_mutex_held = 1;表示该进程不会拿到锁


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值