muduo net库学习笔记7——用于创建服务器的类TcpServer

muduo为每个EventLoop设计了runInLoopqueueInLoop函数用来将本该在其他线程执行的线程不安全函数放到它所属线程执行,从而达到线程安全。

muduo采用采用one loop per thread的设计思想,即每个线程运行一个循环,这里的循环也就是事件驱动循环EventLoop。所以,EventLoop对象的loop函数,包括间接引发的Pollerpoll函数,Channel的handleEvent函数,以及TcpConnectionhandle*函数都是在一个线程内完成的。而在整个muduo体系中,有着多个这样的EventLoop,每个EventLoop都执行着loop,poll,handleEvent,handle*这些函数。这种设计模型也被成为Reactor + 线程池

控制着这些EventLoop的,换句话说,保存着事件驱动循环线程池的,就是TcpServer类,服务器类。TcpServer类创建一个高并发的服务器,内部有一个线程池,线程池中有大量的线程,每个线程运行着一个事件驱动循环,one loop per thread

另外,TcpServer本身也是一个线程(主线程),也运行着一个EventLoop,这个事件驱动循环仅仅用来监控客户端的连接请求,即Acceptor对象的Channel的可读事件。通常如果用户添加定时器任务的话,也会由这个EventLoop监听
但是TcpServer的这个EventLoop不在线程池中,这一点要区分开,线程池中的线程只用来运行负责监控TcpConnection的EventLoop的


TcpServer的成员变量主要以EventLoopAcceptorTcpConnection, EventLoopThreadLoop为主,其它变量主要是各种用户提供的回调函数,大多都传给每一个TcpConnection对象

typedef std::map<string, TcpConnectionPtr> ConnectionMap;

  EventLoop* loop_;  // the acceptor loop
  //TcpServer所在的主线程下运行的事件驱动循环,负责监听Acceptor的Channel 
  
  const string ipPort_;//服务器负责监听的本地ip和端口
  const string name_;//服务器名字,创建时传入
  
  std::unique_ptr<Acceptor> acceptor_; // avoid revealing Acceptor
  //Acceptor对象,负责监听客户端连接请求,运行在主线程的EventLoop中
  
  std::shared_ptr<EventLoopThreadPool> threadPool_;
  //事件驱动线程池,池中每个线程运行一个EventLoop 
  
  ConnectionCallback connectionCallback_;
  //用户传入,有tcp连接到达或tcp连接关闭时调用,传给TcpConnection 
  
  MessageCallback messageCallback_;
  //用户传入,对端发来消息时调用,传给TcpConnection
  
  WriteCompleteCallback writeCompleteCallback_;
  //成功写入内核tcp缓冲区后调用,传给TcpConnection
  
  ThreadInitCallback threadInitCallback_;
  //线程池初始化完成后调用,传给EventLoopThreadPool,再传给每个EventLoopThread
  
  AtomicInt32 started_;
  // always in loop thread
  int nextConnId_;//TcpConnection特有id,每增加一个TcpConnection,nextConnId_加一 
  
  ConnectionMap connections_;//所有的TcpConnection对象,智能指针
};
  • 事件驱动循环EventLoop如上所说,运行在主线程,只用来监听客户端连接请求(Acceptor),不负责监听TcpConnection
  • 事件驱动循环线程池EventLoopThreadPool用于分发线程,当新建TcpConnection时,从线程池中选出一个事件驱动循环线程负责这个TcpConnection
  • connections_std::map<string, shared_ptr<TcpConnection> >类型,在新建TcpConnection后会添加到这个map中,可以保证每个TcpConnection在添加后引用计数为1,保证生命期的正常管理。在tcp连接关闭后会从map中删除TcpConnection,使引用计数减1,为了防止引用计数为0导致没有从TcpConnection的函数中返回就已经将TcpConnection销毁,在removeConnectionInLoop中使用std::bind延长了TcpConnection的生命期,
    ⭐⭐⭐👇
    为了防止引用计数为0导致没有从TcpConnection的函数中返回就已经将TcpConnection销毁,在removeConnectionInLoop中使用std::bind延长了TcpConnection的生命期,

构造函数主要任务是为Acceptor设置回调函数,当有新的客户端连接时由Acceptor接收后调用这个回调函数

TcpServer::TcpServer(EventLoop* loop,
                     const InetAddress& listenAddr,
                     const string& nameArg
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值