前一篇大致讲了一下epoll是个什么东西,优点等内容,这篇延续上一篇的内容,主要是分析epoll的函数,epoll高性能的深入分析。 epoll的三大函数1.创建epoll fd函数 int epoll_create(int size); epoll_create()创建一个epoll的事例,通知内核需要监听size个fd。size指的并不是最大的后备存储设备,而是衡量内核内部结构大小的一个提示。当创建成功后,会占用一个fd,所以记得在使用完之后调用close(),否则fd可能会被耗尽。 Note:自从Linux2.6.8版本以后,size值其实是没什么用的,不过要大于0,因为内核可以动态的分配大小,所以不需要size这个提示了。 创建还有另外一个函数 int epoll_create1(int flag); 这个函数是在linux 2.6.27中加入的,当你在看陈硕的muduo时可以看到这个函数,其实它和epoll_create差不多,不同的是epoll_create1函数的参数是flag,当flag是0时,表示和epoll_create函数完全一样,不需要size的提示了。 当flag = EPOLL_CLOEXEC,创建的epfd会设置FD_CLOEXEC 当flag = EPOLL_NONBLOCK,创建的epfd会设置为非阻塞 一般用法都是使用EPOLL_CLOEXEC. Note:关于FD_CLOEXEC,现在网上好多都说的有点问题,我翻阅了一些资料,请教了一些人,大约明白它的意思了。 它是fd的一个标识说明,用来设置文件close-on-exec状态的。当close-on-exec状态为0时,调用exec时,fd不会被关闭;状态非零时则会被关闭,这样做可以防止fd泄露给执行exec后的进程。关于exec的用法,大家可以去自己查阅下,或者直接man exec。 2.epoll事件的注册函数 int epoll_ctl(int epfd, int op, int fd, struct epoll_event* event); select是在监听时告诉内核要监听的事件,而epoll_ctl是先注册需要监听的事件。 第一个参数epfd,为epoll_create返回的的epoll fd。 第二个参数op表示操作值。有三个操作类型, EPOLL_CTL_ADD // 注册目标fd到epfd中,同时关联内部event到fd上 EPOLL_CTL_MOD // 修改已经注册到fd的监听事件 EPOLL_CTL_DEL // 从epfd中删除/移除已注册的fd,event可以被忽略,也可以为NULL 第三个参数fd表示需要监听的fd。 第四个参数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 */ }; event参数是一个枚举的集合,可以用” | “来增加事件类型,枚举如下: EPOLLIN:表示关联的fd可以进行读操作了。 3.epoll等待事件函数 int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); 上面两个函数的参数含义: 第一个参数:表示epoll_wait等待epfd上的事件 第二个参数:events指针携带有epoll_data_t数据 第三个参数:maxevents告诉内核events有多大,该值必须大于0 第四个参数:timeout表示超时时间(单位:毫秒) epoll_pwait(since linux 2.6.19)允许一个应用程序安全的等待,直到fd设备准备就绪,或者捕获到一个信号量。其中sigmask表示要捕获的信号量。 函数如果等待成功,则返回fd的数字;0表示等待fd超时,其他错误号请查看errno 函数到这里就讲完了,下一篇会写一个例子给大家看下这些函数是如何使用的。 转载请注明:C++爱好者博客 ? 浅析epoll – epoll函数深入讲解 |
|