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 ...
随机推荐
- 亲测:一个完整Vue开发环境搭建。
参考博客飞机: https://www.cnblogs.com/zhaomeizi/p/8483597.html
- cnblogs.com/linycat
核心技术 Java MySQL SSM SpringBoot MyBatisPlus Redis RabbitMQ Git Google ChatGPT 分布式架构 分布式会话 单点登录 分布式锁 读 ...
- KingbaseES V8R3集群维护案例之---pcp_node_refresh应用
案例说明: 在一次KingbaseES V8R3集群切换分析中,运维人员执行了pcp_node_refresh,导致集群发生了failover的切换.此文档对pcp_node_refresh工具做了应 ...
- oracle abs ap 银行账号 组织层 新增api
DECLARE l_return_status VARCHAR2(1); l_msg_count NUMBER; l_msg_data VARCHAR2(1000); x_acct_use_id nu ...
- ipmitool使用报错Could not open device at /dev/ipmi0 or /dev/ipmi/0 or /dev/ipmidev/0: No such file or directory
ipmitool使用报错处理 Could not open device at /dev/ipmi0 or /dev/ipmi/0 or /dev/ipmidev/0: No such file or ...
- [Oracle19C ASM管理] 安装和配置ASM以及Oracle数据库
一般设置 关闭防火墙 检查防火墙状态 systemctl status firewalld.service 暂时关闭防火墙,下次启动时防火墙仍随系统启动而启动 systemctl stop firew ...
- ubuntu系统中NTP服务配置
首先进行软件的安装:sudo apt-get install ntp sudo apt-get install ntpdate(手动校时软件) 然后修改ntp配置文件:sudo vim /etc/nt ...
- 全链路压测SOP
压测模型构建:人工 线上(大促)流量数据 (数据脱敏) 日常流量数据 业务方新的特性产生的变更数据 友商做过的事情 压测模型构建:自动 流程包括:录制-清洗-回放 (目前能做好的公司非常少) 压测标准 ...
- 微信小程序监听view到顶部的高度
view style='width:100%;height:80rpx;' id='navigation'></view> wx.createSelectorQuery().sele ...
- 《Python 3.8从入门到精通(视频教学版)》PDF电子书赠阅
<Python 3.8从入门到精通(视频教学版)>PDF电子书赠阅,个人学习使用,禁止任何形式的商用. https://pan.baidu.com/s/1U_8-N9YJVG8UsUHbQ ...