epollo
epollo 的核心是3个api,它们分别是:
- int epollo_create(int size)
- int epollo_ctl(int epfd,int op, int fd, struct epoll_event *event)
- int epollo_wait(int epfd, stuct epoll_event *events, int maxevents, int timeout)
epollo 的数据结构是1个红黑树和1个链表:
函数解释
int epollo_create(int size)
功能:内核产生一个 epollo 实例数据结构,并返回一个文件描述符 epfd,这个特殊的文件描述符就是 epollo 实例的句柄。size 参数表示要监听文件描述符的最大值,不过已经在后来的 linux 版本中被废弃。
int epollo_ctl(int epfd,int op, int fd, struct epoll_event *event)
功能:用于存储所有监听文件描述符,当添加或者删除一个套间字时,都在红黑树上去处理,红黑树本身插入和删除性能比较好,时间复杂度是 O(logN).
参数:
- epfd:epoll 实例
- op 操作类型:
- EPOLL_CTL_ADD:添加一个需要监听的文件描述符
- EPOLL_CTL_DEL:删除一个已经监听了的文件描述符
- EPOLL_CTL_MOD:修改已经注册的文件描述符监听的而事件
- fd:文件描述符
- epollo_event:表示要监听什么事件
epollo_event 结构:
typedef union epoll_data
{
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t;
struct epoll_event {
__uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
其中 events 表示的是具体的事件,如下:
EPOLLIN //表示对应的文件描述符可以读(包括对端SOCKET正常关闭);
EPOLLOUT //表示对应的文件描述符可以写;
EPOLLPRI //表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);
EPOLLERR //表示对应的文件描述符发生错误;
EPOLLHUP //表示对应的文件描述符被挂断;
EPOLLET //将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。
EPOLLONESHOT//只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里。
int epollo_wait(int epfd, stuct epoll_event *events, int maxevents, int timeout)
功能:阻塞等待注册的事件发生,返回事件的数目,并将触发的事件写入到 events 数组中。
参数:
- maxevents:返回的 events 的最大个数
- timeout:表示在函数调用中阻塞时间上限,单位是 ms
- -1:表示一直阻塞,直到有文件描述符进入 ready 状态或者捕获到信号才返回
- 0:用于非阻塞检测是否有描述符处于ready 状态,立即返回
- 大于0:表示调用将最多持续timeout时间,如果期间有检测对象变为 ready 状态或者捕获到信号则返回,否则直到超时
人的潜力是可以激发的,比如说你给我50斤的砖我可能拎不动,但你要是给我100斤的人民币我肯定拎起来就跑。