C++多线程编程以及epoll处理socket通信时多端口问题

C++多线程编程以及epoll处理socket通信时多端口问题 - 白天的小萤火虫 - 博客园

C++多线程编程以及epoll处理socket通信时多端口问题

问题根源:当有许多客户端用socket来连接我的服务器(期间存在一定的数据交互)的时候,为了提高性能,我们需要采用多线程编程(处理具体的请求),同时还要使用epoll来高效的在IO事件之间切换(侦查socket连接的IO事件)。

这篇随笔,我们主要是写一个单独的模块来解决http到rpc的转化这个问题(本质上来说,有很多开源库来完成这个协议转化的比如XML-RPC,具体需要根据实际情况使用),我们的这么模块需要做其他逻辑,所以自己做了这个工作。

由于我们采用C++编程,有线程池的类写起来和传统的C程序有点不同。

如要在c++下操作线程,有两种办法:
1、第一种:在.CPP文件中,定义不属于某个类的线程处理函数。然后在某个类中调用pthread_create创建线程,并将线程处理函数的地址传给 pthread_create,编译通过。但是不方便处理和调用类中的成员变量或者成员函数,而且.CPP文件单独出现不属于任一类的函数,一定程度上破坏了类的结构,且与C++面向对象设计不符。
2、第二种:在.h头文件中申明static的线程处理函数,编译通过。但是由于处理函数是static静态的,在处理函数中如果再去调用或者处理类的变量和类函数,则也需对应的类变量和类函数都为static静态,这也一定程序破坏了类的结构。解决办法是:调用pthread_create时,pthread_create最后一个参数传进(void*)this指针给线程处理函数 ,这样就可以在static线程处理函数里调用this的类成员变量和类成员函数了

至于epoll的例子,http://blog.csdn.net/haoahua/archive/2008/01/11/2037704.aspx讲的很好。

而之前提出的问题,设计思路则是:创建一个线程池(50)------->生成一个socket sfd并监听某端口,同时生成一个epoll epfd文件描述符并将sfd注册倒epfd中-------->当epoll发现IO有变动的时候,会拿到是什么类型的IO变动,如果是请求类型的变动,则建立新的连接,并同时加入epoll监听;如果不是新的连接,则说明是已有连接的数据到达,则放入循环队列(线程池中的线程会自动处理队列里面的东西)。经同事测试,这样的实现性能很好,qps很轻松的到3000+(开50个线程池的时候)。

http://dev.csdn.net/htmls/55/55394.html这里有一个比较详细的例子,我这里的程序也是在其基础上开发的,主要为了记录:

分析一下epoll,挺有意思的一个东西,其有两种模式,ET和LT,ET模式仅当状态发生变化的时候才获得通知,这里所谓的状态的变化并不包括缓冲区中还有未处理的数据,也就是说,如果要采用ET模式,需要一直 read/write直到出错为止,很多人反映为什么采用ET模式只接收了一部分数据就再也得不到通知了,大多因为这样;而LT模式是只要有数据没有处理就会一直通知下去的。

另外还有一点需要注意,既然是将http协议转化为rpc协议,那么就需要对传入的http请求串进行解析,取出其中有用的部分封装成rpc消息传与后端,对与http协议的描述见http://www.shenmiguo.com/archives/2009/147_http-format.html 主要是GET和POST方法。

 

原文地址:https://www.cnblogs.com/lexus/p/2983652.html