1 MEMCACHED的网络线程模型结构和之前公司的网游服务器底层很相似。
首先,主线程采用非阻塞ACCEPT,它也只干这一件事情,将新连接按照RR轮转,投递给一个工作线程;
投递的方法稍有蹊跷,将新连接PUSH到选定的工作线程的CQ队列中,该队列是线程安全的。
之后主线程往该工作线程所创建的PIPE中写入一个字节,借此唤醒工作线程,以处理新连接;
因为工作线程在启动之初,就创建了PIPE,并用EPOLL监视它的可读条件。
PS:该PIPE可以考虑用eventfd来替代,表现一样。
另外该CQ队列可以考虑作成LOCK_FREE的;不过也没太大必要,因为这里远远不是性能热点。
2 工作者线程将逻辑和IO揉和在一起了。
它监视网络事件,有数据到达,则进行解析并响应。
整个运作过程在drive_machine中实现。
注意conn_new_cmd分支,为了防止饿死,在一条连接上,最多处理50个请求,必须让出CPU。
假如还有请求没有处理完,但是数据已经被应用程序recv到了应用缓冲区;同时客户端在等待结果,并
不再发数据,那么,该连接将进入epoll_wait死等。
为了防止这样的情况,MEMCACHED采用了一个小伎俩:
临时为该连接注册OUT事件,那么epoll_wait将返回,重新进入conn_new_cmd分支,处理余下的请求。
直到所有请求都被处理后,才会取消OUT事件的监视。(在conn_waiting分支中取消的)