使用eventfd唤醒阻塞在select、poll、epoll的IO复用
还是以muduo
为例:
EventLoop
中有两个成员变量与唤醒阻塞的IO复用有关,wakeupFd_
与wakeupChannel_
;
class EventLoop : noncopyable
{public:...void wakeup(); // 唤醒阻塞的IO复用函数...private:...void handleRead(); // wakeupFd_可读时的回调函数private:int wakeupFd_;std::unique_ptr<Channel> wakeupChannel_;
};
wakeupChannel_
是对wakeupFd_
的包装,同时注册了wakeupFd_
的可读事件,可读事件的回调函数是EventLoop::handleRead()
。
EventLoop::EventLoop(): looping_(false),quit_(false),eventHandling_(false),callingPendingFunctors_(false),iteration_(0),threadId_(CurrentThread::tid()),poller_(Poller::newDefaultPoller(this)),timerQueue_(new TimerQueue(this)),wakeupFd_(createEventfd()), // 这是重点wakeupChannel_(new Channel(this, wakeupFd_)),currentActiveChannel_(NULL)
{... wakeupChannel_->setReadCallback(std::bind(&EventLoop::handleRead, this)); // 这是重点// we are always reading the wakeupfdwakeupChannel_->enableReading(); // 这是重点
}
当需要唤醒阻塞在IO复用的主线程时,只需要调用EventLoop::wakeup()
。
void EventLoop::wakeup()
{uint64_t one = 1;ssize_t n = sockets::write(wakeupFd_, &one, sizeof one);if (n != sizeof one){LOG_ERROR << "EventLoop::wakeup() writes " << n << " bytes instead of 8";}
}
ssize_t sockets::write(int sockfd, const void *buf, size_t count)
{return ::write(sockfd, buf, count);
}
它会调用write()
向wakeupFd_
中写入数据,wakeupFd_
变成可读,于是阻塞的IO复用就此返回。
接着EventLoop::handleRead()
被调用。因为muduo
中无论是poll
还是epoll
都被设置为水平触发(level triggered
),
所以wakeupFd_
可读后必须将其中的数据读出,否则它会一直触发可读。处理方式也很简单,直接使用read()
将其中数据读出即可。
void EventLoop::handleRead()
{uint64_t one = 1;ssize_t n = sockets::read(wakeupFd_, &one, sizeof one);if (n != sizeof one){LOG_ERROR << "EventLoop::handleRead() reads " << n << " bytes instead of 8";}
}
需要注意的是,无论是对wakeupFd_
写入还是读出,其操作的对象类型都必须是大于等于8字节的数据类型,可以是int64
或者uint64
。
详细信息可参考:linux进程(线程间)间通信-eventfd
使用eventfd唤醒阻塞在select、poll、epoll的IO复用相关推荐
- Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)
一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 1 简单的启动线程语法 2 def run(na ...
- select poll epoll 高效IO 多路转接
目录 五种常见IO模型 高效IO的概念 阻塞 vs 非阻塞 非阻塞IO fcntl函数 I/O多路转接之select 初识select select函数原型 select操作接口 tcp_server ...
- python3 异步 非阻塞 IO多路复用 select poll epoll 使用
有许多封装好的异步非阻塞IO多路复用框架,底层在linux基于最新的epoll实现,为了更好的使用,了解其底层原理还是有必要的. 下面记录下分别基于Select/Poll/Epoll的echo ser ...
- Python异步非阻塞IO多路复用Select/Poll/Epoll使用
来源:http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架,底层在linux基于最新的epoll实现,为了更好的使用,了解其底层原理 ...
- java nio原理 epoll_多路复用 Select Poll Epoll 的实现原理(BIO与NIO)
BIO blocking阻塞的意思,当我们在后端开发使用的时候,accetp 事件会阻塞主线程. 当accept事件执行的时候,客户的会和服务建立一个socket 连接.一般后端就会开启一个线程执行后 ...
- select,poll,epoll的归纳总结区分
Select.Poll与Epoll比较 以下资料都是来自网上搜集整理.引用源详见文章末尾. 1 Select.Poll与Epoll简介 Select select本质上是通过设置或者检查存放fd ...
- linux poll函数 实现,Linux select/poll/epoll 原理(一)实现基础
本序列涉及的 Linux 源码都是基于 linux-4.14.143 . 1. 文件抽象 与 poll 操作 1.1 文件抽象 在 Linux 内核里,文件是一个抽象,设备是个文件,网络套接字也是个文 ...
- C++面试 select poll epoll之间的区别
目录 摘要 场景描述 Select poll epoll 总结 摘要 先明确几个概念: 面试官问:给我讲讲什么事同步阻塞.异步阻塞.同步非阻塞.异步非阻塞. 我:????? 同步和异步的概念 同步是指 ...
- 彻底搞懂 select/poll/epoll,就这篇了!
之前已经把网络 I/O 相关要点都盘了,还剩 select/poll/epoll 这几个区别没说,这篇就来搞搞它们,并且是从完全理解原理的角度来区分它们. 本来是要上源码的,但是感觉没啥必要,身为应用 ...
- select,poll,epoll区别面试常问
select,poll,epoll区别: select优点 1)select()的可移植性更好,在某些Unix系统上不支持poll() 2)select() 对于超时值提供了更好的精度:微秒,而pol ...
最新文章
- 使用Leangoo做销售管理系统
- shell编程1到10求和_重磅|郑州市第四届中小学创意编程暨智能设计大赛初中组真题解析(下)...
- 4MLinux 24.0 发布
- 【Py面试题】找到数组或整数列表中连续子序列的最大和
- 解决android扫描二维码时,用户禁止权限报错问题
- 【ArcGIS风暴】缓冲区分析、叠置分析综合实验案例:购房区域的选择
- Java (jdk win 10)
- 短小精悍-机器学习核心概念、模型、基础知识点简明手册-免费分享
- 字符转换工具,仿牛族字符转换
- PowerBI功能发布时间线
- 关于启动Activity之间的及普通按钮的点击事件
- Swift - iCloud存储介绍
- Hive表中加载数据的5中方式
- 学会这些VRay渲染器HDRI照明技巧,轻松搞定3ds Max
- 苹果id怎么注册?老果粉教你创建新的Apple ID
- jupyter notebook 基本操作
- Linux-linux系统函数
- 华为鸿蒙os再度升级,华为鸿蒙官网再次更新!多达24款机型可升级鸿蒙OS:赶紧报名升级吧...
- d2lzh_pytorch包离线安装
- svm对未知数据的分类_SVM对sklearn自带手写数字数据集进行分类
热门文章
- Bithumb Global AMA丨Cred加速实现开放金融——打造区块链上蚂蚁金服
- Deepin-15.10-custom-LiveCD 定制版本已经发布
- 给服务器里添加只读用户的脚本
- import 导入模块学习
- 专访飞康新任CEO:云时代下,我们更懂数据保护
- 安装win7和XP双系统的注意事项
- 2.Linux/Unix 系统编程手册(上) -- 基本概念
- 61. Catalog 分类页面商品排序
- php指定时间 n天,PHP实现指定时间的n月之前的这一天的两种算法
- 当使用 position 属性时,请始终设置 !DOCTYPE 声明:当使用 float 属性时,请始终设置 !DOCTYPE 声明: