关于ngx_trylock_accept_mutex的一些解释

关于nginx里面accept互斥锁的处理,群里讨论了很多次,很多人都提出了各种问题,比如问到:在ngx_process_events_and_timers中,为什么在释放ngx_accept_mutex之后,不把ngx_accept_mutex_held清零?

 
  1. if (ngx_accept_mutex_held) {

  2. ngx_shmtx_unlock(&ngx_accept_mutex);

  3. /* 有人说应该加上ngx_accept_mutex_held = 0; */

  4. }

这里我们好好分析一下ngx_trylock_accept_mutex函数,它就能给我们答案:

 
  1. ngx_int_t

  2. ngx_trylock_accept_mutex(ngx_cycle_t *cycle)

  3. {

  4. if (ngx_shmtx_trylock(&ngx_accept_mutex)) {

  5.  
  6. if (ngx_enable_accept_events(cycle) == NGX_ERROR) {

  7. ngx_shmtx_unlock(&ngx_accept_mutex);

  8. return NGX_ERROR;

  9. }

  10.  
  11. ngx_accept_mutex_held = 1;

  12.  
  13. return NGX_OK;

  14. }

  15.  
  16. if (ngx_accept_mutex_held) {

  17. if (ngx_disable_accept_events(cycle) == NGX_ERROR) {

  18. return NGX_ERROR;

  19. }

  20.  
  21. ngx_accept_mutex_held = 0;

  22. }

  23.  
  24. return NGX_OK;

  25. }

对照这个函数,我们假想一个情景,若此时nginx有两个worker,我们称为A和B。当A执行这个函数,并在调用ngx_shmtx_trylock时成功,这时它将listen fd注册到自己的epoll中(即ngx_enable_accept_events),然后ngx_accept_mutex_held被置1。注意哦,这里ngx_enable_accept_events处理之后就将其置1是为了表达listen fd此时被A进程注册到epoll中了。很显然这个时候B进程由于获取accept锁失败,自然就没有权利accept了。当进程A在处理完accept之后,就会释放accept锁,让B在下一轮竞争中能有机会获取锁来做accept。

 
  1. if (ngx_accept_mutex_held) {

  2. ngx_shmtx_unlock(&ngx_accept_mutex);

  3. }

接下来B很争气,获得了accept锁,跟当年进程A一样将listen fd加到epoll中,处理过程如出一辙。这个时候我们来看A进程,由于这次在跟B的较量中败北,但是ngx_accept_mutex_held为true,表明之前曾经注册过listen fd。别忘了失败的代价就是要交出listen fd,皇帝的位置现在由B来做,王冠现在不属于你了。由于此时只有B有权将listen fd注册到自己的epoll中,其他的进程(ngx_accept_mutex_held为true的进程)就要将listen fd从自己的epoll中移除(即ngx_disable_accept_events)。

 
  1. if (ngx_accept_mutex_held) {

  2. if (ngx_disable_accept_events(cycle) == NGX_ERROR) {

  3. return NGX_ERROR;

  4. }

  5. ngx_accept_mutex_held = 0;

  6. }

说到这里大家别混淆了,nginx的epoll是每个进程私有了,可能在有些系统的设计里,epoll是线程(或者进程)共享的。

--------------------- 本文来自 aweth0me 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/brainkick/article/details/9081017?utm_source=copy

猜你喜欢

转载自blog.csdn.net/ai2000ai/article/details/82893590
今日推荐