前言
一、生产者与消费者设计模式
- 某个模块负责产生数据,这些数据由另一个模块来负责处理:
- 产生数据的模块,就形象地称为生产者
- 而处理数据的模块,就称为消费者
- 该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据
- 缓冲区的作用:
- 1.解耦,生产者和消费者只依赖缓冲区,而不相互依赖
- 2.支持并发和异步
二、服务端模型图

三、服务端代码优化
1、分离客户端连接与消息处理业务
- 原先的代码是将每个客户端保存在EasyTcpServer的数组中,并且在EasyTcpServer::Onrun()函数中调用select对每个客户端进行数据监听
- 现在的代码为:
- 保持EasyTcpServer不变,作为生产者,其内部创建一个CellServer对象数组
- 但是客户端不在EasyTcpServer内存储了,创建一个新的class CellServer,作为消费者,其保存客户端的连接,并在CellServer::Onrun()函数中调用select对每个客户端进行数据监听
- EasyTcpServer只接收客户端的连接,接收到客户端的连接之后,将其传递给自己CellServer对象数组中的某一个CellServer对象进行管理
2、为消息处理线程添加新客户端缓冲队列
- 新增一个class CellServer
- 作为消费者,从缓冲区中查看是否有新客户端,如果有那么就将新客户端添加到自己的fd_set中进行select监听
- 新增一个addClient方法,用来向缓冲队列中添加新的客户端
class CellServer
{
public:
CellServer(SOCKET sock = INVALID_SOCKET)
{
_sock = sock;
}
~CellServer()
{
Close();
_sock = INVALID_SOCKET;
}
SOCKET _maxSock;
bool OnRun()
{
_clients_change = true;
while (isRun())
{
if (_clientsBuff.size() > 0)
{
std::lock_guard<std::mutex> lock(_mutex);
for (auto pClient : _clientsBuff)
{
_clients[pClient->sockfd()] = pClient;
}
_clientsBuff.clear();
_clients_change = true;
}
}
}
void addClient(ClientSocket