当前位置: 互联网>综合
本页文章导读:
▪关于ngx_trylock_accept_mutex的一些解释 关于nginx里面accept互斥锁的处理,群里讨论了很多次,很多人都提出了各种问题,比如问到:在ngx_process_events_and_timers中,为什么在释放ngx_accept_mutex之后,不把ngx_accept_mutex_held清零?
if (ngx_acce.........
▪关于ngx_epoll_add_event的一些解释 static ngx_int_t
ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
int op;
uint32_t events, prev;
ngx_event_t *e;
ngx_connection_t *c;
struct epoll_event ee;
c =.........
▪根据ip地址查找本地时区 根据ip地址查找本地时区,非常的方便(多关注屌丝乐园),将下面网址输入到浏览器中,即可查看
http://ipinfodb.com/ip_location_api.php
http://api.ipinfodb.com/v3/ip-city/?key=076b47ff1eefd89fde7cfc1409d808f48949.........
[1]关于ngx_trylock_accept_mutex的一些解释
来源: 互联网 发布时间: 2013-10-25
关于nginx里面accept互斥锁的处理,群里讨论了很多次,很多人都提出了各种问题,比如问到:在ngx_process_events_and_timers中,为什么在释放ngx_accept_mutex之后,不把ngx_accept_mutex_held清零?
if (ngx_accept_mutex_held) { ngx_shmtx_unlock(&ngx_accept_mutex); /* 有人说应该加上ngx_accept_mutex_held = 0; */ }
这里我们好好分析一下ngx_trylock_accept_mutex函数,它就能给我们答案:
ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle) { if (ngx_shmtx_trylock(&ngx_accept_mutex)) { if (ngx_enable_accept_events(cycle) == NGX_ERROR) { ngx_shmtx_unlock(&ngx_accept_mutex); return NGX_ERROR; } ngx_accept_mutex_held = 1; return NGX_OK; } if (ngx_accept_mutex_held) { if (ngx_disable_accept_events(cycle) == NGX_ERROR) { return NGX_ERROR; } ngx_accept_mutex_held = 0; } return NGX_OK; }对照这个函数,我们假想一个情景,若此时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。
if (ngx_accept_mutex_held) { ngx_shmtx_unlock(&ngx_accept_mutex); }
接下来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)。
if (ngx_accept_mutex_held) { if (ngx_disable_accept_events(cycle) == NGX_ERROR) { return NGX_ERROR; } ngx_accept_mutex_held = 0; }
说到这里大家别混淆了,nginx的epoll是每个进程私有了,可能在有些系统的设计里,epoll是线程(或者进程)共享的。
作者:dingyujie 发表于2013-6-12 21:57:58 原文链接
阅读:13 评论:0 查看评论
[2]关于ngx_epoll_add_event的一些解释
来源: 互联网 发布时间: 2013-10-25
static ngx_int_t ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) { int op; uint32_t events, prev; ngx_event_t *e; ngx_connection_t *c; struct epoll_event ee; c = ev->data; events = (uint32_t) event; if (event == NGX_READ_EVENT) { e = c->write; prev = EPOLLOUT; } else { e = c->read; prev = EPOLLIN; } if (e->active) { op = EPOLL_CTL_MOD; events |= prev; } else { op = EPOLL_CTL_ADD; } ee.events = events | (uint32_t) flags; ee.data.ptr = (void *) ((uintptr_t) c | ev->instance); if (epoll_ctl(ep, op, c->fd, &ee) == -1) { return NGX_ERROR; } ev->active = 1; return NGX_OK; }
这就是那个在群里被问了无数遍的函数,在讨论它之前,可以先来看下这个http://blog.csdn.net/dingyujie/article/details/8570764,在这篇文章中特别强调了两个重要变量(即active和ready)的用途。看过之后,再来看这个函数。大家的问题主要是围绕在函数的开头:
为什么明明处理的是NGX_READ_EVENT,即所谓的读事件,为什么要去管c->write?即代码:
if (event == NGX_READ_EVENT) { e = c->write; prev = EPOLLOUT; } else { e = c->read; prev = EPOLLIN; }
其实答案就跟在后面:
if (e->active) { op = EPOLL_CTL_MOD; events |= prev; } else { op = EPOLL_CTL_ADD; }
结合这两段代码,意图就很明显了(明显吗?既然明显,为什么还有不少人在这里被绊住了呢?)。在epoll中监控读写事件时,主要通过接口epoll_ctl来处理。注意使用时有两种操作add和mod,当一个fd第一次注册到epoll时,使用add方式。而如果之前已经添加过对该fd读写事件的监控,就要通过mod来修改原来的监控方式,告知epoll我们的需求。如果一个fd被重复执行add会报错。
man epoll: Q: What happens if you register the same file descriptor on an epoll instance twice? A: You will probably get EEXIST. However, it is possible to add a duplicate (dup(2), dup2(2), fcntl(2) F_DUPFD) descriptor to the same epoll instance. This can be a useful technique for filtering events, if the duplicate file descriptors are registered with dif- ferent events masks.
所以nginx这里就是为了避免这种情况,当要在epoll中加入对一个fd读事件(即NGX_READ_EVENT)的监听时,nginx先看一下与这个fd相关的写事件的状态,即e=c->write,如果此时e->active为1,说明该fd之前已经以NGX_WRITE_EVENT方式被加到epoll中了,此时只需要使用mod方式,将我们的需求加进去,否则才使用add方式,将该fd注册到epoll中。反之处理NGX_WRITE_EVENT时道理是一样的。
作者:dingyujie 发表于2013-6-12 21:16:17 原文链接
阅读:13 评论:0 查看评论
[3]根据ip地址查找本地时区
来源: 互联网 发布时间: 2013-10-25
根据ip地址查找本地时区,非常的方便(多关注屌丝乐园),将下面网址输入到浏览器中,即可查看
http://ipinfodb.com/ip_location_api.php
http://api.ipinfodb.com/v3/ip-city/?key=076b47ff1eefd89fde7cfc1409d808f48949e1eb0f2eb08e66786358d207e81d&ip=42.121.104.51
http://api.ipinfodb.com/v3/ip-country/?key=076b47ff1eefd89fde7cfc1409d808f48949e1eb0f2eb08e66786358d207e81d&ip=42.121.104.51
作者:zhangzhenghe 发表于2013-6-13 16:46:42 原文链接
阅读:0 评论:0 查看评论
最新技术文章: