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;

--解析完毕;

posted @ 2024-01-26 13:22  OzTaking  阅读(1)  评论(0编辑  收藏  举报