小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

linux線程池epoll

 jijo 2008-09-25
epoll用到的所有函數(shù)都是在頭文件sys/epoll.h中聲明的,下面簡要說明所用到的數(shù)據(jù)結構和函數(shù):
所用到的數(shù)據(jù)結構
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 */
};
結構體epoll_event 被用于注冊所感興趣的事件和回傳所發(fā)生待處理的事件,其中epoll_data 聯(lián)合體用來保存觸發(fā)事件的某個文件描述符相關的數(shù)據(jù),例如一個client連接到服務器,服務器通過調用accept函數(shù)可以得到于這個client對應的socket文件描述符,可以把這文件描述符賦給epoll_data的fd字段以便后面的讀寫操作在這個文件描述符上進行。epoll_event 結構體的events字段是表示感興趣的事件和被觸發(fā)的事件可能的取值為:EPOLLIN :表示對應的文件描述符可以讀;
EPOLLOUT:表示對應的文件描述符可以寫;
EPOLLPRI:表示對應的文件描述符有緊急的數(shù)據(jù)可讀(我不太明白是什么意思,可能是類似client關閉 socket連接這樣的事件);
EPOLLERR:表示對應的文件描述符發(fā)生錯誤;
EPOLLHUP:表示對應的文件描述符被掛斷;
EPOLLET:表示對應的文件描述符有事件發(fā)生;
所用到的函數(shù):
1、epoll_create函數(shù)
函數(shù)聲明:int epoll_create(int size)
該函數(shù)生成一個epoll專用的文件描述符,其中的參數(shù)是指定生成描述符的最大范圍(我覺得這個參數(shù)和select函數(shù)的第一個參數(shù)應該是類似的但是該怎么設置才好,我也不太清楚)。
2、epoll_ctl函數(shù)
函數(shù)聲明:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
該函數(shù)用于控制某個文件描述符上的事件,可以注冊事件,修改事件,刪除事件。
參數(shù):epfd:由 epoll_create 生成的epoll專用的文件描述符;
op:要進行的操作例如注冊事件,可能的取值EPOLL_CTL_ADD 注冊、EPOLL_CTL_MOD 修
改、EPOLL_CTL_DEL 刪除
fd:關聯(lián)的文件描述符;
event:指向epoll_event的指針;
如果調用成功返回0,不成功返回-1
3、epoll_wait函數(shù)
函數(shù)聲明:int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout)
該函數(shù)用于輪詢I/O事件的發(fā)生;
參數(shù):
epfd:由epoll_create 生成的epoll專用的文件描述符;
epoll_event:用于回傳代處理事件的數(shù)組;
maxevents:每次能處理的事件數(shù);
timeout:等待I/O事件發(fā)生的超時值;
返回發(fā)生事件數(shù)。
例子:







代碼:


#include <iostream>

#include <sys/socket.h>

#include <sys/epoll.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>



#define MAXLINE 10

#define OPEN_MAX 100

#define LISTENQ 20

#define SERV_PORT 5555

#define INFTIM 1000



void setnonblocking(int sock)

{

int opts;

opts=fcntl(sock,F_GETFL);

if(opts<0)

{

perror("fcntl(sock,GETFL)");

exit(1);

}

opts = opts|O_NONBLOCK;

if(fcntl(sock,F_SETFL,opts)<0)

{

perror("fcntl(sock,SETFL,opts)");

exit(1);

}

}



int main()

{

int i, maxi, listenfd, connfd, sockfd,epfd,nfds;

ssize_t n;

char line[MAXLINE];

socklen_t clilen;

//聲明epoll_event結構體的變量,ev用于注冊事件,數(shù)組用于回傳要處理的事件

struct epoll_event ev,events[20];

//生成用于處理accept的epoll專用的文件描述符

epfd=epoll_create(256);



struct sockaddr_in clientaddr;

struct sockaddr_in serveraddr;

listenfd = socket(AF_INET, SOCK_STREAM, 0);

//把socket設置為非阻塞方式

setnonblocking(listenfd);

//設置與要處理的事件相關的文件描述符

ev.data.fd=listenfd;

//設置要處理的事件類型

ev.events=EPOLLIN|EPOLLET;

//注冊epoll事件

epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);



bzero(&serveraddr, sizeof(serveraddr));

serveraddr.sin_family = AF_INET;



char *local_addr="200.200.200.204";

inet_aton(local_addr,&(serveraddr.sin_addr));//htons(SERV_PORT);

serveraddr.sin_port=htons(SERV_PORT);

bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr));

listen(listenfd, LISTENQ);



maxi = 0;

for ( ; ; ) {

//等待epoll事件的發(fā)生

nfds=epoll_wait(epfd,events,20,500);

//處理所發(fā)生的所有事件

for(i=0;i<nfds;++i)

{

if(events[i].data.fd==listenfd)

{



connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen);

if(connfd<0){

perror("connfd<0");

exit(1);

}

setnonblocking(connfd);



char *str = inet_ntoa(clientaddr.sin_addr);

std::cout<<"connect from "<_u115 ?tr<<std::endl;

//設置用于讀操作的文件描述符

ev.data.fd=connfd;

//設置用于注測的讀操作事件

ev.events=EPOLLIN|EPOLLET;

//注冊ev

epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);

}

else if(events[i].events&EPOLLIN)

{

if ( (sockfd = events[i].data.fd) < 0) continue;

if ( (n = read(sockfd, line, MAXLINE)) < 0) {

if (errno == ECONNRESET) {



close(sockfd);

events[i].data.fd = -1;

} else

std::cout<<"readline error"<<std::endl;

} else if (n == 0) {

close(sockfd);

events[i].data.fd = -1;

}

//設置用于寫操作的文件描述符

ev.data.fd=sockfd;

//設置用于注測的寫操作事件

ev.events=EPOLLOUT|EPOLLET;

//修改sockfd上要處理的事件為EPOLLOUT

epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);

}

else if(events[i].events&EPOLLOUT)

{

sockfd = events[i].data.fd;

write(sockfd, line, n);

//設置用于讀操作的文件描述符

ev.data.fd=sockfd;

//設置用于注測的讀操作事件

ev.events=EPOLLIN|EPOLLET;

//修改sockfd上要處理的事件為EPOLIN

epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
}
}
}
}





    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多