lt與et模式應用場景
參考epoll有兩種工作模式:
邊緣觸發模式(edgetrigger,et)
水平觸發模式(leveltrigger,lt) 預設模式
這兩中模式用電平來表示,
lt模式:
et模式:1. 低電平 => 高電平
2. 處於高電平狀態
socket可讀事件lt觸發條件:1. 低電平 => 高電平
1. socket上無資料 => socket上有資料
2. socket處於有資料狀態
socket可讀事件et觸發條件:
1. socket上無資料 => socket上有資料
2. socket又新來一次資料
socket可寫事件lt觸發條件:
1. socket可寫 => socket可寫
2. socket不可寫 => socket可寫
socket可寫事件et觸發條件:
1. socket不可寫 => socket可寫
該鏈結epoll lt模式和et模式詳解 分別給出了以上四種情況的例項,在這裡給出建議**:
伺服器大致**如下:
// 將監聽套接字註冊到epoll例項中
epoll_event listen_fd_event;
listen_fd_event.data.fd = listenfd;
listen_fd_event.events = epollin;
//將監聽sokcet繫結到epollfd上去
if (epoll_ctl(epollfd, epoll_ctl_add, listenfd, &listen_fd_event) == -1)
// epoll_wait返回各種事件
n = epoll_wait(epollfd, epoll_events, 1024, 1000);
....
for (size_t i = 0; i < n; ++i) else
} else if (epoll_events[i].events & epollerr)
}
如果次數客戶端,對該伺服器傳送abcd
,那麼服務端會輸出,
recv from client:a
recv from client:b
recv from client:c
recv from client:d
// 將監聽套接字註冊到epoll例項中
epoll_event listen_fd_event;
listen_fd_event.data.fd = listenfd;
listen_fd_event.events = epollin;
listen_fd_event.events |= epollet;
//將監聽sokcet繫結到epollfd上去
if (epoll_ctl(epollfd, epoll_ctl_add, listenfd, &listen_fd_event) == -1)
// epoll_wait返回各種事件
n = epoll_wait(epollfd, epoll_events, 1024, 1000);
....
for (size_t i = 0; i < n; ++i) else
} else if (epoll_events[i].events & epollerr)
}
如果次數客戶端,對該伺服器傳送abcd
,那麼服務端會輸出,
recv from client:a
此時注意啊,et模式下只會觸發一次事件,當客戶端再此傳送123
,服務端輸出:
recv from client:b
// 將監聽套接字註冊到epoll例項中
epoll_event listen_fd_event;
listen_fd_event.data.fd = listenfd;
listen_fd_event.events = epollin;
//listen_fd_event.events |= epollet;
//將監聽sokcet繫結到epollfd上去
if (epoll_ctl(epollfd, epoll_ctl_add, listenfd, &listen_fd_event) == -1)
// epoll_wait返回各種事件
n = epoll_wait(epollfd, epoll_events, 1024, 1000);
....
for (size_t i = 0; i < n; ++i) else
}else if (epoll_events[i].events & epollout)
else if (epoll_events[i].events & epollerr)
}
如果客戶端對伺服器發起連線,由於套接字輸出快取可寫,一直觸發可寫事件,因此輸出:
epollout triggered,clientfd:
epollout triggered,clientfd:
epollout triggered,clientfd:
......
// 將監聽套接字註冊到epoll例項中
epoll_event listen_fd_event;
listen_fd_event.data.fd = listenfd;
listen_fd_event.events = epollin;
listen_fd_event.events |= epollet;
//將監聽sokcet繫結到epollfd上去
if (epoll_ctl(epollfd, epoll_ctl_add, listenfd, &listen_fd_event) == -1)
// epoll_wait返回各種事件
n = epoll_wait(epollfd, epoll_events, 1024, 1000);
....
for (size_t i = 0; i < n; ++i) else
}else if (epoll_events[i].events & epollout)
else if (epoll_events[i].events & epollerr)
}
et模式下,可寫事件只會觸發一次,剛連線時服務端輸出
epollout triggered,clientfd:
如果需要再次觸發,客戶端需要再次傳送訊息,比如客戶端傳送abc
,此時服務端會激發寫事件和讀事件,因此輸出
recv from client:abc
epollout triggered,clientfd:
首先給出結論,
et
模式適用高流量的情景下,比如nginx就是使用et模式,比如傳送大檔案et模式較為使用。
一般情況下使用lt模式,比如redis
就是lt模式。
原因:使用et模式,特定場景下會比lt更快,因為它可以便捷的處理epollout事件,省去開啟與關閉epollout的epoll_ctl(epoll_ctl_mod)呼叫。從而有可能讓你的效能得到一定的提公升。
lt**
**大概資訊如下:
當epoll例項監聽套接字有讀事件觸發時,將新產生的連線套接字
註冊到epoll
例項中,事件型別為epollin
。
當連線套接字有請求時,激發讀事件,此時我們讀取套接字內容並進行處理,接著傳送乙個reponsd
。
注意,這裡就需要根據是否一次性發完respond
進行區別:
if (一次性發完) else
像比如et模式,效率就出現再最後乙個updateevents上,如果檔案特別大,是不是這個語句執行的次數就更多,因此大檔案適用於et模式。
et**
**大概資訊如下:
當epoll例項監聽套接字有讀事件觸發時,將新產生的連線套接字
註冊到epoll
例項中,事件型別為epollin | epollout | epollrt
。
當連線套接字有請求時,激發讀事件,此時我們讀取套接字內容並進行處理,接著傳送乙個reponsd
。
這裡就不不需要改變註冊套接字的事件型別。
從上述流程可以看出,像比如et模式,效率就出現再最後乙個updateevents上,如果檔案特別大,是不是這個語句執行的次數就更多,因此大檔案適用於et模式。
epoll lt模式和et模式詳解
epoll的邊沿觸發模式(et)真的比水平觸發模式(lt)快嗎?(當然lt模式也使用非阻塞io,重點是要求et模式下的**不能造成飢餓)
epoll lt/et深入剖析
EPOLL兩種模式
select epoll 的特點 select 的特點 select 選擇控制代碼的時候,是遍歷所有控制代碼,也就是說控制代碼有事件響應時,select 需要遍歷所有控制代碼才能獲取到哪些控制代碼有事件通知,因此效率是非常低。但是如果連線很少的情況下,select 和epoll的lt 觸發模式相比,...
epoll兩種觸發模式
二 詳細 三 測試效果 lt level triggered lt是預設的工作方式,並且同時支援block和no block socket。在這種做法中,核心告訴你乙個檔案描述符是否就緒了,然後你可以對這個就緒的fd進行io操作。如果你不作任何操作,核心還是會繼續通知你的,所以,這種模式程式設計出錯...
epoll兩種模式(lt et)複習
最近又在複習一些基礎知識,現在看看epoll的相關知識點。兩種模式 簡單理解 lt 水平觸發 對於採用lt工作模式的檔案描述符,當epoll wait檢測到其上有事件發生並將此事件通知應用程式後,應用程式可以不立即處理該事件,當應用程式下一次呼叫epoll wait時,epoll waite還會再次...