Muduo类详解之Poller

简介: Muduo类详解之Poller

       负责监听文件描述符事件是否触发以及返回发生事件的文件描述符以及具体事件的模块就是Poller,所以一个Poller对象对应一个事件监听器。

class Epoll {
public:
 Epoll();
 ~Epoll();
 void epoll_add(const sp_Channel& request);
 void epoll_mod(const sp_Channel& request);
 void epoll_del(const sp_Channel& request);
 void poll(std::vector<sp_Channel>& req);
private:
 int epollFd_;
 std::vector<epoll_event> events_; // epoll_wait()返回的活动事件都放在这个数组
 std::unordered_map<int, sp_Channel> channelMap_;
};
  • Poller/EpollPoller的重要成员变量
  • epollfd_: 就是用epoll_create方法返回的epoll句柄,这个是常识。
  • channels_:这个变量是std::unordered_map<int, Channel*>类型,负责记录 文件描述符 —> Channel的映射,也帮忙保管所有- 注册在你这个Poller上的Channel。
  • ownerLoop_:所属的EventLoop对象,看到后面你懂了。

其他函数⽆⾮就是对 Epoll_ctl(4) Epoll_wait(4) 的封装。

void Epoll::poll(std::vector<sp_Channel>& req) {
 int event_count =
 Epoll_wait(epollFd_, &*events_.begin(), events_.size(), EPOLLWAIT_TIME);
 for(int i = 0; i < event_count; ++i) {
 int fd = events_[i].data.fd;
 sp_Channel temp = channelMap_[fd];
 temp->setRevents(events_[i].events);
 req.emplace_back(std::move(temp));
 }
 // LOG << "Epoll finished";
}

      Epoll::poll(1) 这个函数可以说是 Poller 的核⼼了,当外部调⽤ poll ⽅法的时候,该⽅法底层其实是通过 epoll_wait 获取这个事件监听器上发⽣事件的 fd 及其对应发⽣的事件,我们知道每个 fd 都是由⼀个 Channel 封 装的,通过哈希表 channelMap_ 可以根据 fd 找到封装这个 fd 的 Channel 。将 IO 多路复⽤模块监听到该 fd 发⽣ 的事件写进这个 Channel 中的 revents 成员变量中。然后把这个 Channel 装进 req 中。这样,当外界调⽤完 poll 之后就能拿到 IO 多路复⽤模块的 监听结果 ( std::vector<sp_Channel>& req )。

相关文章
|
5月前
muduo源码剖析之Socket类
封装了一个sockfd相关的设置。比较简单,已经编写注释。
49 0
|
5月前
muduo源码剖析之Acceptor监听类
Acceptor类用于创建套接字,设置套接字选项,调用socket()->bind()->listen()->accept()函数,接受连接,然后调用TcpServer设置的connect事件的回调。listen()//在TcpServer::start中调用封装了一个listen fd相关的操作,用于mainLoop接受器封装,实质上就是对Channel的多一层封装监听连接 当新连接进入时,调用Socket::accept创建套接字,触发TcpServer的回调TcpServer通过该接口设置回调,
39 0
|
5月前
|
API
muduo源码剖析之SocketOps类
对socket设置API的封装。比较简单,已经编写注释。
33 0
|
5月前
|
安全 API
muduo源码剖析之EventLoop事件循环类
EventLoop.cc就相当于一个reactor,多线程之间的函数调用(用eventfd唤醒),epoll处理,超时队列处理,对channel的处理。运行loop的进程被称为IO线程,EventLoop提供了一些API确保相应函数在IO线程中调用,确保没有用互斥量保护的变量只能在IO线程中使用,也封装了超时队列的基本操作。
69 0
|
5月前
muduo源码剖析之channel通道类
channel是muduo中的事件分发器,它只属于一个EventLoop,Channel类中保存着IO事件的类型以及对应的回调函数,每个channel只负责一个文件描述符,但它并不拥有这个文件描述符。channel是在epoll和TcpConnection之间起沟通作用,故也叫做通道,其它类通过调用channel的setCallbcak来和建立channel沟通关系。
84 0
|
5月前
muduo源码剖析之Connector客户端连接类
Connector负责主动发起连接,不负责创建socket,只负责连接的建立,外部调用Connector::start就可以发起连接,Connector具有重连的功能和停止连接的功能,连接成功建立后返回到TcpClient。
48 0
|
11月前
19.3 Boost Asio 多线程通信
多线程服务依赖于两个通用函数,首先`boost::bind`提供了一个高效的、简单的方法来创建函数对象和函数对象适配器,它的主要功能是提供了一种将函数和它的参数绑定到一起的方法,这种方法可以将具有参数的成员函数、普通函数以及函数对象转化为不带参数的函数对象。当参数绑定后则下一步就需要使用多线程功能,Boost库中提供了`boost::thread`库,`boost::thread`可以用于创建线程、启动线程、等待线程执行结束以及线程间通信等多种操,有了这两个关键库那么我们只需要`accept.accept(*sock)`等待套接字上线,当有套接字上线后则自动创建`MyThread`子线程,
89 0
19.3 Boost Asio 多线程通信
|
4月前
|
应用服务中间件 Go nginx
Swoole 源码分析之 epoll 多路复用模块
IO多路复用技术通过使用少量的线程或进程同时监视多个IO事件,能够更高效地处理大量的IO操作,从而提高系统的性能和资源利用率。
48 0
Swoole 源码分析之 epoll 多路复用模块
|
5月前
|
前端开发
muduo源码剖析之AsyncLogging异步日志类
AsyncLogging是muduo的日志,程序如果直接让文件写日志可能会发生阻塞,muduo前端设计了2个BufferPtr,分别是currentBuffer_和nextBuffer_,还有一个存放BufferPtr的vector(buffers_)。多个前端线程往currentBuffer_写数据,currentBuffer_写满了将其放入buffers_,通知后端线程读。前端线程将currentBuffer_和nextBuffer_替换继续写currentBuffer_。
57 0
|
5月前
Muduo类详解之EventLoop
Muduo类详解之EventLoop