用pipe唤醒异步select的经典场景
来源:互联网 发布:linux $$ 编辑:程序博客网 时间:2024/06/10 01:39
转自:http://www.zhihu.com/question/39752285/answer/82906915
linux多线程网络编程中有一段话:
当然,pipe也有一个经典应用场景,那就是写Reactor/event loop 时用来唤醒异步select调用?网上没找到具体的应用场景,不知道是怎么唤醒异步调用
linux多线程网络编程中有一段话:
当然,pipe也有一个经典应用场景,那就是写Reactor/event loop 时用来唤醒异步select调用?网上没找到具体的应用场景,不知道是怎么唤醒异步调用
reactor展开了写就是个等待和分发事件的过程:
events = selector.wait(milliseconds)for fd, event in events: if event & EVT_READ: handle_read(fd) if event & EVT_WRITE: handle_write(fd)
问题出在wait上,没新消息它将一直等到milliseconds指定的时间为准,而此时ui上用户说了句话,点击“发送”,ui线程把待发送的内容推到了网络线程的消息队列里,而网络线程还在wait呢,没网络事件的话,只有等待这轮wait结束网络线程才有空到队列里监测并处理刚才ui线程投递过来的待发送消息。
select等待时间过长将会让消息不能即时被处理,而过短又会占用过多cpu费电,因此在想能不能平时wait长一点,而当我ui线程刚点击了发送按钮就立即把网络线程从select的wait中唤醒让网络线程可以即时的查看自己的消息队列就方便了。
于是大家把管道的读取端fd放入selector,那么在wait的时候这个读取端管道fd也会一起参与wait,那么ui线程往队列里塞完任务后,马上往管道的写端写入一个字节,就可以把网络线程唤醒了。
这个方法是用来解决多个reactor之间互相唤醒的问题的,利用该技巧可以让网络线程即时处理网络事件的同时也能即时处理来自非网络(比如内部消息队列)的其它消息。
就是所谓的self pipe trick,说白了也很简单,windows下select只能针对socket套接字,不能针对管道,一般用构造两个互相链接于localhost的socket来模拟之。不过win下select最多支持同时wait 64个套接字,你摸拟的pipe占掉一个,就只剩下63个可用了。
所以java的nio里selector在windows下最多支持62个套接字就是被self pipe trick占掉了两个,一个用于其它线程调用notify唤醒,另一个留作jre内部保留,就是这个原因。
说白了这其实就是个年代久远的系统层api设计考虑不周全,要应用层来给它打补丁的典型例子。
倘若系统层直接支持这样的唤醒,就不用应用层构造什么管道了。
0 0
- 用pipe唤醒异步select的经典场景
- select:windows pipe的模拟
- select pipe
- Scene---场景的异步加载
- Select模型(PIPE)
- windows select pipe
- select唤醒函数
- select 的 poll 异步处理
- select和epoll的应用场景
- Select模型---很经典的
- Select模型---很经典的
- pipe unblock select in linux
- Unity 异步加载场景的代码
- ios嵌套的异步并行任务场景
- 【Unity】场景异步加载的进度条制作
- Unity3D场景异步加载的实现案例
- 同步、异步的使用场景及好处
- 【Unity】场景异步加载的进度条制作
- Hive学习二
- POJ 3264 Balanced Lineup RMQ
- [从头学数学] 第184节 周游列国拜诸侯(中)
- C#引用传递
- HDU 5666 快速就乘
- 用pipe唤醒异步select的经典场景
- __NSCFNumber isEqualToString:的问题.--[__NSCFNumber isEqualToString:]: unrecognized selector sent to in
- vs下,GBK格式的.h .cpp 编译时,自动转换为UTF-8
- Java学习-11天
- 剑指offer面试题 顺时针打印矩阵
- 一个用PHP写的网站,当两个人同时用一个账号登录时,后一个会将前一个账号挤下线。
- leetcode 9 给一个int类型的数字,判断是否是回文数
- codeforces 425A Sereja and Swaps
- Spark 调试