文章目录

从TcpServer开始,找到了EventLoop,在EventLoop中又找到了两个重要组成部分,Chanel和Poller,那就自底向上。

#pragma once#include "nocopyable.hpp"
#include "timestamp.hpp"#include <functional>
#include <memory>   //智能指针需要class EventLoop;    //前置声明,避免过多的头文件包含class Channel:nocpoyable{public:using EventCallback = std::function<void()>;    //设置事件回调名称using ReadEventCallback = std::function<void(timestamp)>; Channel(EventLoop* loop,int fd);    //这里只需要个指针,前置声明无伤大雅~Channel();//fd得到poller事件通知后,处理事件void handleEvent(timestamp receiveTime);    //这里需要初始化了,不能仅仅前置声明,需要包头文件了//设置回调函数对象void setReadCallback(ReadEventCallback cb){ readCallback_ = std::move(cb); }void setWriteCallback(EventCallback cb){ writeCallback_ = std::move(cb); }void setCloseCallback(EventCallback cb){ closeCallback_ = std::move(cb); }void setErrorCallback(EventCallback cb){ errorCallback_ = std::move(cb); }//防止手动remove channel之后,channel还在执行回调操作  void tie(const std::shared_ptr<void>&);int fd() const { return fd_; }int events() const { return events_; }void set_revents(int revt) { revents_ = revt; }// int revents() const { return revents_; }bool isNoneEvent() const { return events_ == kNoneEvent; }void enableReading() { events_ |= kReadEvent; update(); }void disableReading() { events_ &= ~kReadEvent; update(); }void enableWriting() { events_ |= kWriteEvent; update(); }void disableWriting() { events_ &= ~kWriteEvent; update(); }void disableAll() { events_ = kNoneEvent; update(); }bool isWriting() const { return events_ & kWriteEvent; }bool isReading() const { return events_ & kReadEvent; }// for Pollerint index() { return index_; }void set_index(int idx) { index_ = idx; }//one loop per threadEventLoop* ownerLoop() { return loop_; }void remove();private:void update();void handleEventWithGuard(timestamp receiveTime);//事件状态标志static const int kNoneEvent;static const int kReadEvent;static const int kWriteEvent;EventLoop* loop_;   //  事件循环const int fd_;      //poller监听对象int events_;        //注册fd感兴趣的事件int revents_;       //poller返回的具体发生的事情int index_;bool       logHup_;std::weak_ptr<void> tie_;int tied_;bool eventHandling_;bool addedToLoop_;//channel通道可以获知fd最终发生的具体时间revents,所以它负责调用具体事件的回调操作ReadEventCallback readCallback_;EventCallback writeCallback_;EventCallback closeCallback_;EventCallback errorCallback_;};
#include"channel.hpp"
#include"eventloop.hpp"
#include"logger.hpp"#include<sys/epoll.h>//事件状态标志
const int kNoneEvent = 0;
const int kReadEvent = EPOLLIN | EPOLLPRI;
const int kWriteEvent = EPOLLOUT;Channel::Channel(EventLoop* loop,int fd): loop_(loop),fd_(fd),events_(0),revents_(0),index_(-1),logHup_(true),tied_(false),eventHandling_(false),addedToLoop_(false)
{}Channel::~Channel(){}void Channel::tie(const std::shared_ptr<void> &obj){tie_ = obj;tied_ = true;
}//当改变了channel所表示的fd的events事件后,update负责在poller中修改fd相应事件的epoll_ctl
void Channel::update(){/*当channel所属的EventLoop调用poller的相应方法,注册fd的events事件add code...*/
}//用完了把自己咔嚓了
void Channel::remove(){//add code...
}void Channel::handleEvent(timestamp receiveTime){if (tied_){     //对于tied_的在哪里被修改使用目前是个未知数std::shared_ptr<void> guard = tie_.lock();if (guard){handleEventWithGuard(receiveTime);}}else{handleEventWithGuard(receiveTime);}}//根据具体接收到的事件,执行相应的回调操作
void Channel::handleEventWithGuard(timestamp receiveTime){LOG_INFO("channel handleEvent revents:%d",revents_);if((revents_ & EPOLLHUP) && !(revents_ & EPOLLIN)){ //发生异常if(closeCallback_){closeCallback_();}}if(revents_ & EPOLLERR){    //发生错误if(errorCallback_){errorCallback_();}}//有可读事件if(revents_ & (EPOLLIN | EPOLLPRI)){if(readCallback_){readCallback_(receiveTime);}}//有可写事件if(revents_ & EPOLLOUT){if(writeCallback_){writeCallback_();}}
}

缩略版muduo网络库(2):事件处理器 Chanel相关推荐

  1. muduo网络库使用心得

    上个月看了朋友推荐的mudo网络库,下完代码得知是国内同行的开源作品,甚是敬佩.下了mudo使用手冊和035版的代码看了下结构,感觉是一个比較成熟并且方便使用的网络库.本人手头也有自己的网络库,尽管不 ...

  2. muduo网络库学习(八)事件驱动循环线程池EventLoopThreadPool

    muduo是支持多线程的网络库,在muduo网络库学习(七)用于创建服务器的类TcpServer中也提及了TcpServer中有一个事件驱动循环线程池,线程池中存在大量线程,每个线程运行一个Event ...

  3. muduo网络库学习(七)用于创建服务器的类TcpServer

    目前为止,涉及到的绝大多数操作都没有提及线程,EventLoop,Poller,Channel,Acceptor,TcpConnection,这些对象的执行都是在单独线程完成,并没有设计多线程的创建销 ...

  4. muduo网络库学习(四)事件驱动循环EventLoop

    muduo的设计采用高并发服务器框架中的one loop per thread模式,即一个线程一个事件循环. 这里的loop,其实就是muduo中的EventLoop,所以到目前为止,不管是Polle ...

  5. muduo网络库源码阅读Step by Step

    Posted on: Nov 26 2015 Categories: muduo C++ Tags: muduo 一般写服务端程序都需要有一个称手的网络库来帮我们处理琐碎的网络通信细节,比如连接的建立 ...

  6. 基于C++11的muduo网络库

    文章目录 写在前面 项目编译问题 库安装的问题 项目测试代码 关于压力测试 项目概述 muduo网络库的reactor模型 muduo的设计 muduo各个类 辅助类 NonCopyable Time ...

  7. muduo网络库源码复现笔记(十七):什么都不做的EventLoop

    Muduo网络库简介 muduo 是一个基于 Reactor 模式的现代 C++ 网络库,作者陈硕.它采用非阻塞 IO 模型,基于事件驱动和回调,原生支持多核多线程,适合编写 Linux 服务端多线程 ...

  8. muduo网络库的封装

    一.基础socket编程 网络编程的底层离不开socket,其处理流程表示如下: int sockfd = socket(AF_INET, SOCK_STREAM, 0);struct sockadd ...

  9. muduo网络库浅谈(一)

    muduo网络库浅谈(一) 序言 第一章 muduo的关键结构 class EventLoop class Channel class Poller 番外 定时任务 class Timestamp c ...

最新文章

  1. 字节总监的开发手记,知乎5000+点赞!
  2. mysql timestamp json_mysql中timestamp,datetime,int类型的区别与优劣
  3. 有关电子的十个有趣事实
  4. Android使用adb抓完整Log
  5. Python 中的 if __name__ == __main__ 该如何理解
  6. nodejs 向mongodB获取指定数目的数据
  7. 高德最佳实践:Serverless 规模化落地有哪些价值?
  8. netty系列之:netty中各不同种类的channel详解
  9. Discuz 升级X3问题汇总整理
  10. Chrome谷歌浏览器76地址栏隐藏的HTTPS和WWW标记如何恢复
  11. 参数估计法——最大似然估计和贝叶斯参数估计
  12. js 一个关于图片onload加载的事
  13. 深入理解Scala 标识符,命名和域
  14. phpstudy php56 zend,phpstudy集成环境
  15. 微信小程序│ 游戏开发 │连连看游戏
  16. 【LOG】函数使用技巧
  17. windows下网络诊断基本命令
  18. Python爬取多网页表格数据(非table)
  19. 根据用户输入的总行数(奇数),打印出菱形(总行数与总列数相等)。
  20. 地产AR模拟看房软件开发

热门文章

  1. 微信小程序-贪吃蛇开发5 游戏界面设计,flex布局
  2. VC-dimension
  3. 标量、向量、张量的区别
  4. LAA : random fourier features的又一应用
  5. hdl四位二进制计数器_quartus4位二进制加减法计数器.doc
  6. 第0次作业 成绩统计
  7. Linux下的softlink和symbolic link(hardlink)
  8. [洛谷]P1936 水晶灯火灵 (#递推 -1.3)
  9. 修改你的 Debian 系统语言
  10. 苹果App Store公布最新应用审核标准