eventPollerPool-Pipe 分析
1.eventPoller 分析
1.1 event设置:
基本知识
详见man epoll
Level-triggered and edge-triggered /水平触发 和边沿触发/
LT: 水平触发 没有标识;
ET: 边沿触发 EPOLLET;
默认触发方式是水平触发,什么标识都不用指定,
如果要指定边沿触发,则指定为EPOLLET;
参考文章:
https://blog.csdn.net/albertsh/article/details/123958013
对于水平触发模式,一个事件只要有,就会一直触发。
对于边缘触发模式,只有一个事件从无到有才会触发。
LT模式下,读事件触发后,可以按需收取想要的字节数,不用把本次接收到的数据收取干净,
ET模式下,读事件触发后通常需要数据一次性收取干净。
---zltoolKit定义
在eventPoller类中定义了:
typedef enum {
Event_Read = 1 << 0, //读事件
Event_Write = 1 << 1, //写事件
Event_Error = 1 << 2, //错误事件
Event_LT = 1 << 3,//水平触发
} Poll_Event;
event的不同的事件,zltoolKit 先使用LT水平触发,否则才使用ET边沿触发;
Event_Read、Event_Write、Event_Error、Event_LT 都是zltoolkit自己定义的
其中还定义了;
//防止epoll惊群
#ifndef EPOLLEXCLUSIVE
#define EPOLLEXCLUSIVE 0
#endif
解析:
ev.events = (toEpoll(event)) | EPOLLEXCLUSIVE;
设置event的掩码类型,用于设置不同的类型:
在文件EventPoller.cpp定义了宏如下:
#define toEpoll(event) (((event) & Event_Read) ? EPOLLIN : 0) \
| (((event) & Event_Write) ? EPOLLOUT : 0) \
| (((event) & Event_Error) ? (EPOLLHUP | EPOLLERR) : 0) \
| (((event) & Event_LT) ? 0 : EPOLLET)
ev.events = (toEpoll(event)) | EPOLLEXCLUSIVE;
代入展开:
#define toEpoll(event) (((event) & Event_Read) ? EPOLLIN : 0) \
| (((event) & Event_Write) ? EPOLLOUT : 0) \
| (((event) & Event_Error) ? (EPOLLHUP | EPOLLERR) : 0) \
| (((event) & Event_LT) ? 0 : EPOLLET) | EPOLLEXCLUSIVE
方式:
使用条件运算符:
event与Event_Read、Event_Write、Event_Error、Event_LT 分别按位求“与&”,
如果求的值是true,则使用“:”前面的表达式,否则使用后面的表达式;
因此:
Event_Read 与 EPOLLIN 是一致的;
Event_Write 与 EPOLLOUT 是一致的;
Event_Error 与EPOLLHUP| EPOLLERR 是一致的;
Event_LT 与0是一致的,否则就是 边沿触发,EPOLLET | EPOLLEXCLUSIVE;
特别注意:
注意在电平选择的方式:
例如:
((event) & Event_LT) ? 0 : EPOLLET)
如果是LT水平触发,设置为0;否则设置为边沿触发EPOLLET;
--解析完毕;