日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

epoll事件模型

發布時間:2023/11/30 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 epoll事件模型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

事件模型

EPOLL事件有兩種模型:

Edge Triggered (ET) 邊緣觸發只有數據到來才觸發,不管緩存區中是否還有數據。

Level Triggered (LT) 水平觸發只要有數據都會觸發。

思考如下步驟:

  • 假定我們已經把一個用來從管道中讀取數據的文件描述符(RFD)添加到epoll描述符。
  • 管道的另一端寫入了2KB的數據
  • 調用epoll_wait,并且它會返回RFD,說明它已經準備好讀取操作
  • 讀取1KB的數據
  • 調用epoll_wait……
  • 在這個過程中,有兩種工作模式:

    ET模式

    ET模式即Edge Triggered工作模式。

    如果我們在第1步將RFD添加到epoll描述符的時候使用了EPOLLET標志,那么在第5步調用epoll_wait之后將有可能會掛起,因為剩余的數據還存在于文件的輸入緩沖區內,而且數據發出端還在等待一個針對已經發出數據的反饋信息。只有在監視的文件句柄上發生了某個事件的時候 ET 工作模式才會匯報事件。因此在第5步的時候,調用者可能會放棄等待仍在存在于文件輸入緩沖區內的剩余數據。epoll工作在ET模式的時候,必須使用非阻塞套接口,以避免由于一個文件句柄的阻塞讀/阻塞寫操作把處理多個文件描述符的任務餓死。最好以下面的方式調用ET模式的epoll接口,在后面會介紹避免可能的缺陷。

    1)????? 基于非阻塞文件句柄

    2)????? 只有當read或者write返回EAGAIN(非阻塞讀,暫時無數據)時才需要掛起、等待。但這并不是說每次read時都需要循環讀,直到讀到產生一個EAGAIN才認為此次事件處理完成,當read返回的讀到的數據長度小于請求的數據長度時,就可以確定此時緩沖中已沒有數據了,也就可以認為此事讀事件已處理完成。

    LT模式

    LT模式即Level Triggered工作模式。

    與ET模式不同的是,以LT方式調用epoll接口的時候,它就相當于一個速度比較快的poll,無論后面的數據是否被使用。

    LT(level triggered):LT是缺省的工作方式,并且同時支持block和no-block socket。在這種做法中,內核告訴你一個文件描述符是否就緒了,然后你可以對這個就緒的fd進行IO操作。如果你不作任何操作,內核還是會繼續通知你的,所以,這種模式編程出錯誤可能性要小一點。傳統的select/poll都是這種模型的代表。

    ET(edge-triggered):ET是高速工作方式,只支持no-block socket。在這種模式下,當描述符從未就緒變為就緒時,內核通過epoll告訴你。然后它會假設你知道文件描述符已經就緒,并且不會再為那個文件描述符發送更多的就緒通知。請注意,如果一直不對這個fd作IO操作(從而導致它再次變成未就緒),內核不會發送更多的通知(only once).

    實例一:

    基于管道epoll ET觸發模式

    ?

    #include <stdio.h> #include <stdlib.h> #include <sys/epoll.h> #include <errno.h> #include <unistd.h>#define MAXLINE 10int main(int argc, char *argv[]) {int efd, i;int pfd[2];pid_t pid;char buf[MAXLINE], ch = 'a';pipe(pfd);pid = fork();if (pid == 0) {close(pfd[0]);while (1) {for (i = 0; i < MAXLINE/2; i++)buf[i] = ch;buf[i-1] = '\n';ch++;for (; i < MAXLINE; i++)buf[i] = ch;buf[i-1] = '\n';ch++;write(pfd[1], buf, sizeof(buf));sleep(2);}close(pfd[1]);} else if (pid > 0) {struct epoll_event event;struct epoll_event resevent[10];int res, len;close(pfd[1]);efd = epoll_create(10);/* event.events = EPOLLIN; */event.events = EPOLLIN | EPOLLET; /* ET 邊沿觸發 ,默認是水平觸發 */event.data.fd = pfd[0];epoll_ctl(efd, EPOLL_CTL_ADD, pfd[0], &event);while (1) {res = epoll_wait(efd, resevent, 10, -1);printf("res %d\n", res);if (resevent[0].data.fd == pfd[0]) {len = read(pfd[0], buf, MAXLINE/2);write(STDOUT_FILENO, buf, len);}}close(pfd[0]);close(efd);} else {perror("fork");exit(-1);}return 0; }

    水平觸發:

    運行結果:

    ubuntu1604@ubuntu:~/wangqinghe/linux/20190827$ ./et

    res 1

    aaaa

    res 1

    bbbb

    res 1

    cccc

    res 1

    dddd

    res 1

    eeee

    res 1

    ffff

    ^C

    實例二:

    基于網絡C/S模型的epoll ET觸發模式

    server

    ?

    /* server.c */ #include <stdio.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include <signal.h> #include <sys/wait.h> #include <sys/types.h> #include <sys/epoll.h> #include <unistd.h>#define MAXLINE 10 #define SERV_PORT 8080int main(void) {struct sockaddr_in servaddr, cliaddr;socklen_t cliaddr_len;int listenfd, connfd;char buf[MAXLINE];char str[INET_ADDRSTRLEN];int i, efd;listenfd = socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));listen(listenfd, 20);struct epoll_event event;struct epoll_event resevent[10];int res, len;efd = epoll_create(10);event.events = EPOLLIN | EPOLLET; /* ET 邊沿觸發 ,默認是水平觸發 */printf("Accepting connections ...\n");cliaddr_len = sizeof(cliaddr);connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);printf("received from %s at PORT %d\n",inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),ntohs(cliaddr.sin_port));event.data.fd = connfd;epoll_ctl(efd, EPOLL_CTL_ADD, connfd, &event);while (1) {res = epoll_wait(efd, resevent, 10, -1);printf("res %d\n", res);if (resevent[0].data.fd == connfd) {len = read(connfd, buf, MAXLINE/2);write(STDOUT_FILENO, buf, len);}}return 0; }

    client

    /* client.c */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <netinet/in.h>#define MAXLINE 10 #define SERV_PORT 8080int main(int argc, char *argv[]) {struct sockaddr_in servaddr;char buf[MAXLINE];int sockfd, i;char ch = 'a';sockfd = socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);servaddr.sin_port = htons(SERV_PORT);connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));while (1) {for (i = 0; i < MAXLINE/2; i++)buf[i] = ch;buf[i-1] = '\n';ch++;for (; i < MAXLINE; i++)buf[i] = ch;buf[i-1] = '\n';ch++;write(sockfd, buf, sizeof(buf));sleep(10);}Close(sockfd);return 0; }

    ?

    邊沿觸發:

    運行結果:

    ubuntu1604@ubuntu:~/wangqinghe/linux/20190827$ ./et

    res 1

    aaaa

    res 1

    bbbb

    res 1

    cccc

    ^C

    ?

    實例三:

    基于網絡C/S非阻塞模型的epoll ET觸發模式

    server

    /* server.c */ #include <stdio.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/wait.h> #include <sys/types.h> #include <sys/epoll.h> #include <unistd.h> #include <fcntl.h>#define MAXLINE 10 #define SERV_PORT 8080int main(void) {struct sockaddr_in servaddr, cliaddr;socklen_t cliaddr_len;int listenfd, connfd;char buf[MAXLINE];char str[INET_ADDRSTRLEN];int i, efd, flag;listenfd = socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));listen(listenfd, 20);struct epoll_event event;struct epoll_event resevent[10];int res, len;efd = epoll_create(10);/* event.events = EPOLLIN; */event.events = EPOLLIN | EPOLLET; /* ET 邊沿觸發 ,默認是水平觸發 */printf("Accepting connections ...\n");cliaddr_len = sizeof(cliaddr);connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);printf("received from %s at PORT %d\n",inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),ntohs(cliaddr.sin_port));flag = fcntl(connfd, F_GETFL);flag |= O_NONBLOCK;fcntl(connfd, F_SETFL, flag);event.data.fd = connfd;epoll_ctl(efd, EPOLL_CTL_ADD, connfd, &event);while (1) {printf("epoll_wait begin\n");res = epoll_wait(efd, resevent, 10, -1);printf("epoll_wait end res %d\n", res);if (resevent[0].data.fd == connfd) {while ((len = read(connfd, buf, MAXLINE/2)) > 0)write(STDOUT_FILENO, buf, len);}}return 0; }

    client

    /* client.c */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <netinet/in.h>#define MAXLINE 10 #define SERV_PORT 8080int main(int argc, char *argv[]) {struct sockaddr_in servaddr;char buf[MAXLINE];int sockfd, i;char ch = 'a';sockfd = socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);servaddr.sin_port = htons(SERV_PORT);connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));while (1) {for (i = 0; i < MAXLINE/2; i++)buf[i] = ch;buf[i-1] = '\n';ch++;for (; i < MAXLINE; i++)buf[i] = ch;buf[i-1] = '\n';ch++;write(sockfd, buf, sizeof(buf));sleep(10);}Close(sockfd);return 0; }

    ?

    轉載于:https://www.cnblogs.com/wanghao-boke/p/11425936.html

    總結

    以上是生活随笔為你收集整理的epoll事件模型的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美黑人做爰爽爽爽 | 欧美成人午夜免费视在线看片 | 欧美一区二区三区婷婷月色 | www.射| 黄色视屏免费 | 激情免费视频 | 天堂中文在线观看视频 | 美女的隐私免费看 | 天堂在线91| 国产精品一卡 | 视频在线不卡 | 亚洲乱仑 | 亚洲自拍图片 | 澳门黄色一级片 | 1024精品一区二区三区日韩 | 久国久产久精永久网页 | 国产免费视频 | 亚洲三区在线观看无套内射 | 成人久久网 | 久久成人在线 | 欧美国产三级 | www成年人 | 国产又猛又粗 | 国产精品熟妇一区二区三区四区 | 成人免费在线视频网站 | 欧美日韩一区二区综合 | jizz在线观看视频 | 亚洲国产精品久久久久婷婷老年 | 午夜av网站 | 黄色一级视频免费 | xxxx色 | 欧美1314 | 91黄色国产 | 国产色秀 | 青青国产精品视频 | 亚洲一区二区三区四区 | 欧美成人国产精品一区二区 | 中文字幕被公侵犯的漂亮人妻 | 日本免费不卡 | 一级特黄aa大片 | 欧美日韩黄色大片 | 狠狠摸狠狠操 | 成人理论视频 | 亚洲网站在线观看 | 中文字幕在线2019 | 胖女人做爰全过程 | 在线观看欧美日韩 | 国产一区久久 | 禁果av一区二区三区 | 影音先锋啪啪 | 精品一区二区三区免费视频 | 萌白酱在线观看 | 猛男大粗猛爽h男人味 | 青青草官网 | 一区二区精品国产 | 亚洲第一二三区 | 国产精品国产三级国产aⅴ浪潮 | 诱惑の诱惑筱田优在线播放 | 91麻豆国产福利精品 | 91极品美女 | 欧美福利网 | 日韩在线色 | 国产污污视频 | 在线不卡av | 亚洲精品自拍偷拍 | 成年人视频在线免费看 | 97人妻人人揉人人躁人人 | 好吊视频在线观看 | 日韩中文字幕免费视频 | 亚洲字幕成人中文在线观看 | 国产一级免费大片 | 亚洲精品国产91 | 亚洲第一黄色网 | 国产美女免费看 | 亚洲高清一区二区三区 | 激情婷婷色 | 免费看成人aa片无码视频羞羞网 | 欧美毛片在线 | 性欧美丰满熟妇xxxx性仙踪林 | 男人日女人在线观看 | 一级高清毛片 | 免费无码肉片在线观看 | 欧美性猛交xxxx乱大交3 | www.av72| chinese hd av | 黄色一级片在线播放 | 日日cao| 欧美第一视频 | 国产九九九九九 | 91在线视频播放 | 免费观看理伦片在线播放视频软件 | 日本综合色 | 久久久久久久久久久久久女国产乱 | 精品成人无码久久久久久 | 天天操天天操天天操天天操 | 阿v视频免费在线观看 | 在线观看久| 成人性视频网站 | 97超级碰碰人妻中文字幕 |