生活随笔
收集整理的這篇文章主要介紹了
epoll 边沿触发(ET 模式)和水平触发(LT 模式)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
(1)應用 ET 模式的目的:改變 epoll_wait 的默認屬性,可以減少調用 epoll_wait 函數的調用次數。
(2)思想由來:模擬電路的高低電頻的思想。
水平觸發: 持續的 1 持續的 0
邊沿觸發: 0 ->1 ;1 -> 0
(3)場景:
用 epoll 實現一個服務器,調用 epoll_wait 函數進行監聽,此時 client 給 epoll 發送了 100 字節的數據,而 server 使用 read 函數讀走 50 字節,剩余 50 字節,問題:epoll_wait 函數還觸發么?
對于水平觸發來說應該觸發: 因為緩存區內還有數據沒讀完,你需要一直告知我。
2對于邊沿觸發來說不應該觸發:因為 epoll_wait 的職責是告知 server 是否有讀事件發生,我已經告知一次了,但是你有沒有讀完,你的事,我不管 。
(4)使用:默認是水平觸發,若設置邊沿觸發,需要對監聽事件的基礎上加宏 EPOLLET。
(5)邊沿觸發實例:
#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <errno.h>
#include <unistd.h>
#define MAXLINE 10
int main(int argc
, char *argv
[])
{int efd
, i
; char buf
[MAXLINE
], ch
= 'a';int pfd
[2]; pipe(pfd
); pid_t 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(5);} 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
| EPOLLET
; event
.data
.fd
= pfd
[0];epoll_ctl(efd
, EPOLL_CTL_ADD
, pfd
[0], &event
); while (1) {res
= epoll_wait(efd
, resevent
, 10, -1); 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;
}
結果:
水平觸發結果:
父進程 epoll_wait 阻塞(epollt 認為沒數據才是讀事件結束,沒有次數限制)。
父進程 epoll_wait 阻塞。
邊沿觸發結果:
父進程 epoll_wait 阻塞(epollt 認為每讀一次就是讀事件結束)。
父進程 epoll_wait 阻塞。
與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的epoll 边沿触发(ET 模式)和水平触发(LT 模式)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。