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 ...
随机推荐
- C++和C中的输入输出总结、标准输入/标准输出/标准错误与重定向,>>、>、<、<<
标准输入/标准输出/标准错误与重定向 0表示标准输入.1表示标准输出.2标准错误.1和2都是默认是输出到屏幕. linux中的>>.>.<.<<:这些符号是Linu ...
- BundleFusion_Ubuntu_Pangolin 安装的一些error
/usr/bin/ld: 找不到 -lEigen3::Eigen 解决方法:find_package(Eigen3 REQUIRED)为list(APPEND CMAKE_INCLUDE_PATH & ...
- cookie报错 :服务器异常An invalid character [32] was present in the Cookie value
String KaptchaOwner= CommunityUtil.generateUUID(); Cookie cookie=new Cookie("kaptchaOwner" ...
- Camstar获取回参
public static bool SplitQty(string Username, string Password, string Container, int splitQty,int pla ...
- 二.navicate
navicat -创建 -新建查询 -转储sql文件命令: 转储当前目录所有的文件与数据:mysqldump -u root db4 > db4.sql -p 转储当前目录到表结构没有数据:my ...
- mybatis_01 初运行
maven坐标 <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</ ...
- python缩小放大浏览器
driver.execute_script("document.body.style.zoom='70%'") driver.execute_script("docume ...
- 强烈推荐的elasticsearch集群连接工具: elasticvue
个人感觉非常棒的es-cluster连接工具, 检查状态什么的, 一目了然, 支持中文超方便, 比elasticSearchHead好用多了. 安装方法打开微软浏览器edge-商城搜索-Elastic ...
- 解题报告:Codeforces 279C Ladder
Codeforces 279C Ladder 本题与tbw这篇博客上的题有相似思路.tbw的本来我还不会,抄了题解才过,这道题好歹自己磕半天磕出来了.到tbw做那道题我突然想明白了,再一想诶跟这里不是 ...
- kernel32.dll函数简介
kernel32.dll是非常重要的32位动态链接库文件,属于内核级文件.它控制着系统的内存管理.数据的输入输出操作和中断处理,当Windows启动时,kernel32.dll就驻留在内存中特定的写保 ...