epoll 非阻塞IO 邊沿觸發模式
與之前的epoll預設的水平觸發模式相比
epoll的非阻塞IO模式,利用邊沿觸發模式,同時修改read()函式模式為非阻塞讀取,這樣在減少epoll_wait()函式呼叫的同時也實現了水平觸發的效果,是對epoll最優的模式。
伺服器端
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<string.h>
#include<arpa/inet.h>
#include<sys/epoll.h>
#include<errno.h>
#include<ctype.h>
#define MAXLINE 8196
#define SERV_PORT 6666
#define OPEN_MAX 1000
#define SERV_IP "127.0.0.1"
void perr_exit(const char *str)
{
perror(str);
exit(1);
}
int main(int argc,char *argv[])
{
int i,n;
int listenfd,sockfd,connfd;
ssize_t nready,efd,res;
char buf[MAXLINE],str[INET_ADDRSTRLEN];
socklen_t clie_len;
int flag;
struct sockaddr_in clie_addr,serv_addr;
struct epoll_event tep,ep[OPEN_MAX];
listenfd=socket(AF_INET,SOCK_STREAM,0);
int opt=1;
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));//埠複用
bzero(&serv_addr,sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
//serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
inet_pton(AF_INET,SERV_IP,&serv_addr.sin_addr.s_addr);
serv_addr.sin_port=htons(SERV_PORT);
bind(listenfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));//繫結IP和埠
listen(listenfd,128);
efd=epoll_create(OPEN_MAX);//建立epoll模型,efd指向紅黑樹根節點
if(efd==-1)
perr_exit("epoll error!");
tep.events=EPOLLIN | EPOLLET; //邊沿觸發模式
printf("accept connect...\n");
clie_len=sizeof(clie_addr);
connfd=accept(listenfd,(struct sockaddr *)&clie_addr,&clie_len);
printf(" connect client ip:%s---port:%d\n",
inet_ntop(AF_INET,&clie_addr.sin_addr.s_addr,str,sizeof(str)),
ntohs(clie_addr.sin_port)
);
flag=fcntl(connfd,F_GETFL);//修改connfd為非阻塞讀
flag |= O_NONBLOCK;
fcntl(connfd,F_SETFL,flag);
tep.data.fd=connfd;
epoll_ctl(efd,EPOLL_CTL_ADD,connfd,&tep);
while(1)
{
printf("***************************************\n");
printf("epoll_wait begin\n");
res=epoll_wait(efd,ep,10,-1);
printf("epoll_wait end %ld\n",res);
if(ep[0].data.fd==connfd)
{
while((n=read(connfd,buf,5))>0)
write(STDOUT_FILENO,buf,n);
}
}
return 0;
}
測試結果
從截圖看,只用呼叫一次epoll_wait()函式就可以讀取所有資料。
客戶端
伺服器端
相關文章
- [作業系統]阻塞io 非阻塞io Epoll作業系統
- 【Linux網路程式設計-7】epoll邊沿觸發Linux程式設計
- 阻塞IO與非阻塞IO
- 「linux」例項淺析epoll的LT和ET模式,ET模式為何要使用非阻塞IOLinux模式
- IO模式和IO多路複用(阻塞IO、非阻塞IO、同步IO、非同步IO等概念)模式非同步
- IO通訊模型(二)同步非阻塞模式NIO(NonBlocking IO)模型模式BloC
- python之IO併發-阻塞IO 非阻塞IO IO多路複用 非同步IO(協程)Python非同步
- FastAPI之阻塞式io和非阻塞式ioASTAPI
- IO模式 select、poll、epoll模式
- java同步非阻塞IOJava
- Java 非阻塞 IO 和非同步 IOJava非同步
- IO - 同步 非同步 阻塞 非阻塞的區別非同步
- Linux 阻塞和非阻塞 IO 實驗學習Linux
- 談談對不同I/O模型的理解 (阻塞/非阻塞IO,同步/非同步IO)模型非同步
- 11、協程和io教程01 -- 併發 並行 同步 非同步 阻塞 非阻塞 以及 IO多路複用並行非同步
- 從時間碎片角度理解阻塞IO模型及非阻塞模型模型
- 【死磕NIO】— 阻塞IO,非阻塞IO,IO複用,訊號驅動IO,非同步IO,這你真的分的清楚嗎?非同步
- 如何解讀 Java IO、NIO 中的同步阻塞與同步非阻塞?Java
- 玩轉 PHP 網路程式設計全套阻塞與非阻塞 IOPHP程式設計
- 流?I/O 操作?阻塞?epoll?
- 阻塞式IO
- 如何給女朋友解釋什麼是IO中的阻塞、非阻塞、同步、非同步?非同步
- 邊緣觸發ET和水平觸發LT
- 同步非同步,阻塞非阻塞非同步
- 非同步、同步、阻塞、非阻塞非同步
- Java網路程式設計和NIO詳解5:Java 非阻塞 IO 和非同步 IOJava程式設計非同步
- Linux IO模式及 select、poll、epoll詳解(含部分例項原始碼)Linux模式原始碼
- 同步、非同步,阻塞、非阻塞理解非同步
- 同步、非同步、阻塞與非阻塞非同步
- 驅動Driver-阻塞&非阻塞
- 同步非同步 與 阻塞非阻塞非同步
- 理解阻塞、非阻塞、同步、非同步非同步
- ♻️同步和非同步;並行和併發;阻塞和非阻塞非同步並行
- IO多路複用(一)– Select、Poll、Epoll
- 高階IO模型之kqueue和epoll模型
- 併發-0-同步/非同步/阻塞/非阻塞/程式/執行緒非同步執行緒
- 程式執行緒、同步非同步、阻塞非阻塞、併發並行執行緒非同步並行
- 同步、非同步、阻塞、非阻塞的區別非同步