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\r\n");
(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\r\n");
(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的回調函數里面來做相應的處理。
