epoll详解-epoll学习笔记

 未完成。。。。。

 

 关于接口:

主要三大接口,epoll_create,epoll_ctl和epoll_wait。

 

epoll_create

原型

extern int epoll_create (int __size) __THROW;

实例化epoll,返回epfd,epoll的fd。参数就是个size,你想让epoll保证能处理多少连接(只是保证),影响不大吧,新内核都不要传参了,参数空着用就行。
还有一个参数是flags的epoll_create1,我跟他不熟。

 

PS:_THROW宏——是说可能有异常抛出——这样定义的原因是兼容C和C++,C什么都不做,C++用throw()

</usr/include/argp.h> #ifndef __THROW   #define __THROW #endif  #ifndef __THROW   #ifndef __GNUC_PREREQ      #define __GNUC_PREREQ(maj,min) (0)   #endif #if defined __cplusplus && __GNUC_PREREQ(2,8)   #define __THROW     throw() #else    #define __THROW #endif #endif 


 

epoll_ctl

原型

extern int epoll_ctl (int __epfd, int __op, int __fd,
                      struct epoll_event *__event) __THROW;


epoll_wait

原型

extern int epoll_wait (int __epfd, struct epoll_event *__events,
                       int __maxevents, int __timeout);


 

 

 

 

 

关于结构体

 

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 */
};


 核心数据结构就是这个struct epoll_event,根据epoll三大接口可知,epoll_event提供了两大功能。

epoll_ctl接口中,event作为事件的属性设置,设置给定的fd到底进行什么监听操作。此功能主要利用了struct epoll_event的events成员。

提供了EPOLLIN、EPOLLONESHOT等枚举选项,可以或操作,取并集,这些枚举是互相独立不干扰的,其实就是位操作。

 

enum EPOLL_EVENTS
  {
    EPOLLIN = 0x001,
#define EPOLLIN EPOLLIN
    EPOLLPRI = 0x002,
#define EPOLLPRI EPOLLPRI
    EPOLLOUT = 0x004,
#define EPOLLOUT EPOLLOUT
    EPOLLRDNORM = 0x040,
#define EPOLLRDNORM EPOLLRDNORM
    EPOLLRDBAND = 0x080,
#define EPOLLRDBAND EPOLLRDBAND
    EPOLLWRNORM = 0x100,
#define EPOLLWRNORM EPOLLWRNORM
    EPOLLWRBAND = 0x200,
#define EPOLLWRBAND EPOLLWRBAND
    EPOLLMSG = 0x400,
#define EPOLLMSG EPOLLMSG
    EPOLLERR = 0x008,
#define EPOLLERR EPOLLERR
    EPOLLHUP = 0x010,
#define EPOLLHUP EPOLLHUP
    EPOLLRDHUP = 0x2000,
#define EPOLLRDHUP EPOLLRDHUP
    EPOLLONESHOT = (1 << 30),
#define EPOLLONESHOT EPOLLONESHOT
    EPOLLET = (1 << 31)
#define EPOLLET EPOLLET
  };

仔细算就知道了,反正就是一个32位标志,每个设置都占用不同位,没有冲突,甚至从这看还剩余了很多。

 

epoll_wait中epoll_event是接收事件用的,这就用到epoll_event的第二个成员变量了——data。

data是epoll_data_t类型,epoll_data_t就是结构体前边定义的那个联合体。

联合体的结构初看会比较怪异,有个void*指针,有个int fd,剩下uint32_t和uint64_t,fd肯定就是fd了,就是暂不知道打算什么时候用,指针就是核心了,这是给你用的。

uint32_t和uint64_t是干什么的?

好像是没用的!他们只是对齐用的。就因为那个void *指针。

指针是寻址用的,指针长短取决于硬件,或者说系统,64位和32位系统指针长度不一样,这个联合体epoll_data长短就会有不同,相应的,结构体epoll_event长短就会不同,这就比较麻烦了。所以联合体(是联合体,按最长的算)多加了一个u32和一个u64。

这样长度就统一了,移植会比较方便。


ET/LT模式

沿用了通信的术语,edge trigger和level trigger,关于状态,前者是来时候只通知一次,后者是一直可知。
 

 关于使用

这有时候会犯点小错误,因为有个例子工程里有了epoll.h,封装了一些epoll初始化实例化操作,他又没在epoll.h引用sys/epoll.h,而是在epoll.c中引用坏习惯。

(PS:实例化epoll_event,sizeof,他提示你sizeof不能用于不完全的类型,这其实就是没有引用头文件,该数据结构无定义)。

在某文件想使用epoll时用成了

#include "epoll.h"


其实正经的epoll头文件,至少我目前用到的linux,都是

#include <sys/epoll.h>

当然写成双引号也无妨,但是必须是sys。也可以引用epoll.h再让epoll.h去引用sys/epoll.h,这都无所谓

相应的,我用

_EPOLL_H

判定也没问题了,因为系统的是

_SYS_EPOLL_H

 

 

 

 

 

 

 

你可能感兴趣的:(epoll详解-epoll学习笔记)