epoll.docx

上传人:b****7 文档编号:10008881 上传时间:2023-02-07 格式:DOCX 页数:14 大小:17.83KB
下载 相关 举报
epoll.docx_第1页
第1页 / 共14页
epoll.docx_第2页
第2页 / 共14页
epoll.docx_第3页
第3页 / 共14页
epoll.docx_第4页
第4页 / 共14页
epoll.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

epoll.docx

《epoll.docx》由会员分享,可在线阅读,更多相关《epoll.docx(14页珍藏版)》请在冰豆网上搜索。

epoll.docx

epoll

在ACE中有一个TP_Reactor是基于select的..就是可以多线程轮循select

1.线程1用select去轮循fd_set,结束后.获得可读的所有句柄.然后将这些句柄从集合中删掉.然后去操作这些可读句柄

2.线程2用select去轮循fd_set(不包含刚才已经可读的句柄).

3......

因为select是每次循环都要重新加载fd_set.所以可以这样实现多线程轮循.

但epoll的话是一次性的,如果将每次可读的fd都调用EPOLL_CTL_DEL将其从events队列中行色匆除.我觉得可能得不到预期的高效.因为使用epoll的环境毕竟是fd量比较大的情况

2008-3-2712:

12cofish

搜一下就能搜到了

我再贴一次吧

[code]

#include

#include

#include

#include

#include

#include

#include

#include

#include

#defineMAXLINE10

#defineOPEN_MAX100

#defineLISTENQ20

#defineSERV_PORT5555

#defineINFTIM1000

//线程池任务队列结构体

structtask

{

intfd;//需要读写的文件描述符

structtask*next;//下一个任务

};

//用于读写两个的两个方面传递参数

structuser_data

{

intfd;

unsignedintn_size;

charline[MAXLINE];

};

//线程的任务函数

void*readtask(void*args);

void*writetask(void*args);

//声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件

structepoll_eventev,events[20];

intepfd;

pthread_mutex_tmutex;

pthread_cond_tcond1;

structtask*readhead=NULL,*readtail=NULL,*writehead=NULL;

voidsetnonblocking(intsock)

{

intopts;

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);

}

}

intmain()

{

inti,maxi,listenfd,connfd,sockfd,nfds;

pthread_ttid1,tid2;

structtask*new_task=NULL;

structuser_data*rdata=NULL;

socklen_tclilen;

pthread_mutex_init(&mutex,NULL);

pthread_cond_init(&cond1,NULL);

//初始化用于读线程池的线程

pthread_create(&tid1,NULL,readtask,NULL);

pthread_create(&tid2,NULL,readtask,NULL);

//生成用于处理accept的epoll专用的文件描述符

epfd=epoll_create(256);

structsockaddr_inclientaddr;

structsockaddr_inserveraddr;

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.222";

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事件的发生

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

//处理所发生的所有事件

for(i=0;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<<"connec_from>>"<

:

endl;

//设置用于读操作的文件描述符

ev.data.fd=connfd;

//设置用于注测的读操作事件

ev.events=EPOLLIN|EPOLLET;

//注册ev

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

}

elseif(events[i].events&EPOLLIN)

{

printf("reading!

\n");

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

continue;

new_task=newtask();

new_task->fd=sockfd;

new_task->next=NULL;

//添加新的读任务

pthread_mutex_lock(&mutex);

if(readhead==NULL)

{

readhead=new_task;

readtail=new_task;

}

else

{

readtail->next=new_task;

readtail=new_task;

}

//唤醒所有等待cond1条件的线程

pthread_cond_broadcast(&cond1);

pthread_mutex_unlock(&mutex);

}

elseif(events[i].events&EPOLLOUT)

{

rdata=(structuser_data*)events[i].data.ptr;

sockfd=rdata->fd;

write(sockfd,rdata->line,rdata->n_size);

deleterdata;

//设置用于读操作的文件描述符

ev.data.fd=sockfd;

//设置用于注测的读操作事件

ev.events=EPOLLIN|EPOLLET;

//修改sockfd上要处理的事件为EPOLIN

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

}

}

}

}

void*readtask(void*args)

{

intfd=-1;

unsignedintn;

//用于把读出来的数据传递出去

structuser_data*data=NULL;

while

(1)

{

pthread_mutex_lock(&mutex);

//等待到任务队列不为空

while(readhead==NULL)

pthread_cond_wait(&cond1,&mutex);

fd=readhead->fd;

//从任务队列取出一个读任务

structtask*tmp=readhead;

readhead=readhead->next;

deletetmp;

pthread_mutex_unlock(&mutex);

data=newuser_data();

data->fd=fd;

if((n=read(fd,data->line,MAXLINE))<0)

{

if(errno==ECONNRESET)

{

close(fd);

}else

std:

:

cout<<"readlineerror"<

:

endl;

if(data!

=NULL)

deletedata;

}

elseif(n==0)

{

close(fd);

printf("Clientcloseconnect!

\n");

if(data!

=NULL)

deletedata;

}

else

{

data->n_size=n;

//设置需要传递出去的数据

ev.data.ptr=data;

//设置用于注测的写操作事件

ev.events=EPOLLOUT|EPOLLET;

//修改sockfd上要处理的事件为EPOLLOUT

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

}

}

}

[/code]

[code]

/*-------------------------------------------------------------------------------------------------

gcc-oepolldepoll.c-lpthread

author:

wyezl

2006.4.28

---------------------------------------------------------------------------------------------------*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#definePORT8888

#defineMAXFDS5000

#defineEVENTSIZE100

#defineBUFFER"HTTP/1.1200OK\r\nContent-Length:

5\r\nConnection:

close\r\nContent-Type:

text/html\r\n\r\nHello"

intepfd;

void*serv_epoll(void*p);

voidsetnonblocking(intfd)

{

intopts;

opts=fcntl(fd,F_GETFL);

if(opts<0)

{

fprintf(stderr,"fcntlfailed\n");

return;

}

opts=opts|O_NONBLOCK;

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

{

fprintf(stderr,"fcntlfailed\n");

return;

}

return;

}

intmain(intargc,char*argv[])

{

intfd,cfd,opt=1;

structepoll_eventev;

structsockaddr_insin,cin;

socklen_tsin_len=sizeof(structsockaddr_in);

pthread_ttid;

pthread_attr_tattr;

epfd=epoll_create(MAXFDS);

if((fd=socket(AF_INET,SOCK_STREAM,0))<=0)

{

fprintf(stderr,"socketfailed\n");

return-1;

}

setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(constvoid*)&opt,sizeof(opt));

memset(&sin,0,sizeof(structsockaddr_in));

sin.sin_family=AF_INET;

sin.sin_port=htons((short)(PORT));

sin.sin_addr.s_addr=INADDR_ANY;

if(bind(fd,(structsockaddr*)&sin,sizeof(sin))!

=0)

{

fprintf(stderr,"bindfailed\n");

return-1;

}

if(listen(fd,32)!

=0)

{

fprintf(stderr,"listenfailed\n");

return-1;

}

pthread_attr_init(&attr);

pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

if(pthread_create(&tid,&attr,serv_epoll,NULL)!

=0)

{

fprintf(stderr,"pthread_createfailed\n");

return-1;

}

while

(1)

{

cfd=accept(fd,(structsockaddr*)&cin,&sin_len);

if(cfd<=0)

{

sleep

(1);

continue;

}

setnonblocking(cfd);

ev.data.fd=cfd;

ev.events=EPOLLIN|EPOLLET;

if(epoll_ctl(epfd,EPOLL_CTL_ADD,cfd,&ev)<0)

{

close(cfd);

}

//printf("connectfrom%s\n",inet_ntoa(cin.sin_addr));

//printf("cfd=%d\n",cfd);

}

if(fd>0)

close(fd);

return0;

}

void*serv_epoll(void*p)

{

inti,ret,cfd,nfds;

structepoll_eventev,events[EVENTSIZE];

charbuffer[512];

while

(1){

nfds=epoll_wait(epfd,events,EVENTSIZE,-1);

//printf("nfds...........%d\n",nfds);

for(i=0;i

{

if(events[i].events&EPOLLIN)

{

cfd=events[i].data.fd;

ret=recv(cfd,buffer,sizeof(buffer),0);

//printf("readret..........=%d\n",ret);

ev.data.fd=cfd;

ev.events=EPOLLOUT|EPOLLET;

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

}

elseif(events[i].events&EPOLLOUT)

{

cfd=events[i].data.fd;

ret=send(cfd,buffer,strlen(buffer),0);

//printf("sendret...........=%d\n",ret);

ev.data.fd=cfd;

epoll_ctl(epfd,EPOLL_CTL_DEL,cfd,&ev);

//shutdown(cfd,1);

if(cfd>0)

close(cfd);

}

}

}

returnNULL;

}

[/code]

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 职业教育 > 职业技术培训

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1