Epoll的使用例子
本篇文章在上一篇的基础上,使用 epoll 实现了一个事件监听和回调处理的模块。如何编写一个使用该模块的例子呢? 监测什么类型的fd,监测什么类型的事件,监测到事件以后需要做什么?后来可以看看如何将该模块与socket , 回调函数, 线程池联系起来。
#include<sys/epoll.h> // epoll_create, epoll_ctl, epoll_wait
#include <mutex> // std::mutex
#include <functional> // std::function
#include <iostream>
#include <memory> // std::unique_ptr
#include <unistd.h> // close class Epoll{
public:
class ActiveEvents {
public:
ActiveEvents( int num, const struct epoll_event* events):
num_( num ),
events_( events )
{
}
int num() const { return num_; }
const struct epoll_event* events() const { return events_; } private:
int num_;
const struct epoll_event* events_;
}; Epoll();
~Epoll(); int AddMonitorReadableEvent( int fd );
int AddMonitorWritableEvent( int fd );
int DeleteMonitoringEvent( int fd );
int ModifyMonitorEvent( int fd , int status ); void StartPolling();
void HandleEvents( int num, const struct epoll_event* events );
void Stop(); using EpollAwakeCallBack = std::function< void(const ActiveEvents*) > ;
void SetAwakeCallBack( EpollAwakeCallBack* cb ); // 设置事件处理回调函数 private :
int Add_Event( int fd, int event ); // 封装 epoll_ctl, 使函数语义看起来更明确
int Delete_Event( int fd, int event );
int Modify_Event( int fd, int event ); int epollfd_;
std::unique_ptr< EpollAwakeCallBack > awake_cb_ ;
static const int fd_size_; // 最多能处理的fd个数
std::mutex awake_cb_mutex_; // 由于使用std::unique_ptr保存回调函数指针,设置回调函数时需要加锁
std::mutex mutex_;
}; const int Epoll::fd_size_ = 100 ; Epoll::Epoll() {
epollfd_ = epoll_create(fd_size_);
std::cout << "epollfd = " << epollfd_ << std::endl;
} Epoll::~Epoll() {
std::cout << "deleting epoll" << std::endl;
close(epollfd_);
} void Epoll::StartPolling() {
const int EPOLLEVENTS = 100;
struct epoll_event events[EPOLLEVENTS];
while (1) {
auto ret = epoll_wait(epollfd_, events, EPOLLEVENTS, -1);
std::cout << "awakening " << ret << std::endl;
HandleEvents(ret, events);
}
} void Epoll::HandleEvents(int num, const struct epoll_event* events) {
ActiveEvents active_events(num, events);
std::unique_lock<std::mutex> lock(awake_cb_mutex_);
if (awake_cb_) {
(*awake_cb_)(&active_events);
}
} void Epoll::SetAwakeCallBack(EpollAwakeCallBack* cb) {
std::unique_lock<std::mutex> lock(awake_cb_mutex_);
awake_cb_.reset(cb);
} int Epoll::AddMonitorReadableEvent(int fd) {
// TODO: Are epoll_wait and epoll_ctl thread-safe?
std::unique_lock<std::mutex> lock(mutex_);
return Add_Event(fd, EPOLLIN | EPOLLONESHOT);
} int Epoll::AddMonitorWritableEvent(int fd) {
std::unique_lock<std::mutex> lock(mutex_);
return Add_Event(fd, EPOLLOUT | EPOLLONESHOT);
} int Epoll::DeleteMonitoringEvent(int fd) {
std::unique_lock<std::mutex> lock(mutex_);
return Delete_Event(fd, EPOLLIN | EPOLLONESHOT);
} int Epoll::ModifyMonitorEvent(int fd, int status) {
std::unique_lock<std::mutex> lock(mutex_);
return Modify_Event(fd, status);
} int Epoll::Add_Event(int fd, int event) {
struct epoll_event ev;
ev.events = event;
ev.data.fd = fd;
int ret = epoll_ctl(epollfd_, EPOLL_CTL_ADD, fd, &ev);
return ret;
} int Epoll::Delete_Event(int fd, int event) {
struct epoll_event ev;
ev.events = event;
ev.data.fd = fd;
int ret = epoll_ctl(epollfd_, EPOLL_CTL_DEL, fd, &ev);
return ret;
} int Epoll::Modify_Event(int fd, int event) {
struct epoll_event ev;
ev.events = event;
ev.data.fd = fd;
int ret = epoll_ctl(epollfd_, EPOLL_CTL_MOD, fd, &ev);
return ret;
} int main(){
Epoll a;
return 0;
}
Epoll的使用例子的更多相关文章
- 一个epoll的简单例子
epoll事件机制的触发方式有两种:LT(电平触发)和ET(边沿触发) EPOLLIN事件: 内核中的socket接收缓冲区 为空(低电平) 内核中的socket接受缓冲区 不为空(高电平) EPOL ...
- Epoll简介以及例子
第一部分:Epoll简介 问题 : Select,Poll和Epoll的区别 答案 : Epoll和Select的区别 1. 遍历方式的区别.select判断是否有事件发生是遍历的,而epoll是事 ...
- epoll 系列函数简介、与select、poll 的区别
一.epoll 系列函数简介 #include <sys/epoll.h> int epoll_create(int size); int epoll_create1(int flags) ...
- epoll学习
一.epoll_create #include <sys/epoll.h> int epoll_create(int size); int epoll_create1(int flags) ...
- Redis事件管理(一)
Redis统一的时间管理器,同时管理文件事件和定时器, 这个管理器的定义: #if defined(__APPLE__) #define HAVE_TASKINFO 1 #endif /* Test ...
- Redis事件管理(三)
Redis的事件管理和定时器的管理都是自己来实现的,Redis的事件管理分为两部分,一部分是封装了系统的异步事件API,还有一部分是在这基础上封装了一个通用的事件管理器,根据具体的系统来决定具体使用哪 ...
- epoll 简单介绍及例子
第一部分:Epoll简介 . 当select()返回时,timeout参数的状态在不同的系统中是未定义的,因此每次调用select()之前必须重新初始化timeout和文件描述符set.实际上,秒,然 ...
- (转)浅析epoll – epoll例子以及分析
原文地址:http://www.cppfans.org/1419.html 浅析epoll – epoll例子以及分析 上篇我们讲到epoll的函数和性能.这一篇用用这些个函数,给出一个最简单的epo ...
- epoll完整例子
#include <deque> #include <map> #include <vector> #include <pthread.h> #incl ...
- epoll+socket的简单测试例子
server: #include <sys/socket.h> #include <sys/epoll.h> #include <netinet/in.h> #in ...
随机推荐
- 使用std::string的结构不能使用memset
使用了std::string作为成员变量的结构体,千万不能使用memset进行初始化,否则程序会爆
- 记录web面经
1. npm版本号含义 例如: 2.3.1 (分别表示: 大版本,小版本, 补丁版本)大版本号: 大版本更新,功能添加,向下不兼容.小版本号:功能新增,向下兼容.补丁版本号: 修复bug.~符号含义: ...
- JSONObject.parseObject syntax error,expect START WITH { OR [,but actually START WITH error
JSONObject.parseObject syntax error,expect START WITH { OR [,but actually START WITH error解析JSON出现异常 ...
- uniapp全局黑白
page{filter: grayscale(100%); } .uni-tabbar__item{filter: grayscale(100%); }
- Ubuntu 18.04 安装基本应用
Ubuntu 谷歌浏览器下载:第一步打开终端,在终端输入下载命令wget https://dl.google.com/linux/direct/google-chrome-stable_current ...
- IBM服务器的2种IMM和1种raid管理方式
IMM两种进入方式和Raid管理软件 前面板IMM管理接口: 用网线连接服务器前置面板的管理接口到其他 PC 或笔记本,然后 PC 或笔记本的 IP 地址配置为 192.168.70.0/24 ...
- apt-get update 报错 Repository ' InRelease' changed its 'Suite' value from 'stable' to 'oldstable'
问题截图: 解决方案: apt-get update --allow-releaseinfo-change
- hibernate的校验
//不使用@valid进行校验Set<ConstraintViolation<CommonValidator>> validates = validator.validateV ...
- python IDLE清除窗口内容和new file里代码加行业的操作
这个其实比较简单,主要是从网上下载好ClearWindow.py这个文件,然后把文件放到./Lib/idlelib下面,同时打开该文件夹下config-extensions.def文件,在文件尾加入下 ...
- Java基于springboot大学生宿舍寝室考勤人脸识别管理系统
简介 Java基于springboot开发的大学生寝室管理系统宿舍管理系统.学生可以查找寝室和室友信息,可以申请换寝室,申请维修,寝室长提交考勤信息(宿管确认学生考勤信息),补签,查看寝室通报,宿管信 ...