转自:http://www.cnblogs.com/snake-hand/archive/2012/08/13/2636229.html
1、简介
epoll是linux提供的一种异步的I/O通知方式,相比较于select机制而言,select是轮询的,而epoll是触发式的,而且select的最大连接数只有1024,超过这个限制后就只能使用多进程来操作了。所以epoll的效率相对而言更高。
2、主要函数
epoll_create 创建epoll
epoll_ctl 把某个句柄添加到epoll里面
epoll_wait 等待epoll事件的产生。只要注册的句柄发生了变化即会检查到有epoll事件的产生。
3、主要流程
/* 创建EPOLL*/ iEpollFd = epoll_create(MYPING_EPOLLEVENT_MAX);
/* 设置sicket选项 */
stServaddr.ucLen = sizeof(stServaddr); stServaddr.ucFamily = (UCHAR)AF_LIPC; stServaddr.usPort = htons(LIPC_GLOBAL_PORT_MYPING); stServaddr.usAddr = htons(LIPC_LIP_ADDR_ANY); /* 创建 socket */ iLipcFd = socket(PF_LIPC, SOCK_DGRAM, LIPC_PROTO_STCP);
/* bind socket */ iRet += bind(iLipcFd, (struct sockaddr *)(&stServaddr), (UINT)sizeof(LIPC_SOCK_ADDR_S)); /* listen socket */ iRet += listen(iLipcFd, SOMAXCONN); /* bind or listen error */ if(0 != iRet) { printf("bind or listen socket failed "); (VOID)close(iLipcFd); return ERROR_FAILED; } /* regist socket to epoll */ iRet = MYPING_EpollReg(EPOLLIN, iLipcFd, MYPING_LipcListenCallback); if(0 != iRet) { printf("regist lipc socket to epoll failed "); (VOID)close(iLipcFd); return ERROR_FAILED; }
/* 等待事件的产生 */
for(;;) { /* this will be blocked until any registered event happend or timeout */ iNfds = epoll_wait(g_iEpollHandle, astEpEvt, MYPING_EPOLLEVENT_MAX, -1); /* 轮询产生的事件 */ for(i = 0; i < iNfds; i ++) { /* 获取注册的回调函数 */ pfCallback = (VOID *)(ULONG)astEpEvt[i].callback; /* 调用相关的回调函数进行处理 */ pfCallback(astEpEvt[i].events, astEpEvt[i].data.fd); } }
4、机制
实际上一般先在epoll上面注册一个监听的socket,当这个socket监听到有数据连接时,即创建一个新的socket来接收数据,然后把这个新的socket的句柄注册到epoll上面去,再在这个 socket的回调函数里面来做相应的处理。