epoll是做為乙個虛擬檔案系統來實現的,這樣做至少有以下兩個好處:
1、可以在核心裡維護一些資訊,這些資訊在多次
epoll_wait
間是保持的,比如所有受監控的檔案描述符。
2、epoll
本身也可以被
poll/epoll
; 【1】
epoll
的實現中,所等待的裝置就緒後,便呼叫
call_back
函式,把該裝置加入到就緒佇列中,避免了像
poll
那樣裝置就緒後再次輪詢所有裝置找就緒者,由
o(n)
降到o(1)
。 傳統的
poll
函式相當於每次呼叫都重起爐灶,從使用者空間完整讀入
ufds
,完成後再次完全拷貝到使用者空間,另外每次
poll
都需要對所有裝置做至少做一次加入和刪除等待佇列操作,這些都是低效的原因。
3、epoll
的實現**在
fs/eventpoll.c
中。【2
】中最後簡略介紹了一下實現函式,可以看到,
epoll
等待佇列及呼叫函式。
linux的等待佇列,實質上是**函式佇列;【
3】的後文,有
epoll
與poll
等形象對比。
add_wait_queue(whead, &pwq->wait);
4、epoll
儲存拷入的
fd,通過
epoll_ctl
把所有fd
傳入核心再一起
"wait"
,這就省掉了不必要的重複拷貝。其次,在
epoll_wait
時,也不是把
current
輪流的加入
fd對應的裝置等待佇列,而是在裝置等待佇列醒來時呼叫乙個**函式(當然,這就需要「喚醒**」機制),把產生事件的
fd歸入乙個鍊錶,然後返回這個鍊錶上的fd。
乙個新建立的
epoll
檔案帶有乙個
struct eventpoll
結構,這個結構上再掛乙個紅黑樹,而這個紅黑樹就是每次
epoll_ctl時fd
存放的地方!【4,
5】5、建立
struct eppoll_entry
,設定其喚醒**函式為
ep_poll_callback
,然後加入裝置等待佇列。只有這樣,當裝置就緒,喚醒等待佇列上的等待
fd時,
ep_poll_callback
就會被呼叫。每次呼叫
poll
系統呼叫,作業系統都要把
current
(當前程序)掛到
fd對應的所有裝置的等待佇列上,可以想象,
fd多到上千的時候,這樣「掛」法很費事;而每次呼叫
epoll_wait
則沒有這麼羅嗦,
epoll
只在epoll_ctl
時把current
掛一遍(這第一遍是免不了的)並給每個
fd乙個命令「好了就調**函式」,如果裝置有事件了,通過**函式,會把
fd放入
rdllist
,而每次呼叫
epoll_wait
就只是收集
rdllist
裡的fd
就可以了——
epoll
巧妙的利用**函式,實現了更高效的事件驅動模型。
ep_poll_callback會幹什麼了——肯定是把紅黑樹上的收到
event
的epitem
(代表每個
fd)插入
ep->rdllist
中,這樣,當
epoll_wait
返回時,
rdllist
裡就都是就緒的
fd了!
比喻如下【3】
就像收本子的班長,以前(
poll
)得乙個個學生地去問有沒有本子,如果沒有,它還得等待一段時間而後又繼續問(輪詢),現在好了,只走一次(
epoll_ctl
),如果沒有本子,班長就告訴大家去那裡交本子
(等待佇列,**函式
),當班長想起要取本子,就去那裡看看或者等待一定時間後離開(
epoll_wait
),有本子到了就叫醒他,然後取走。
6、linux
系統的優點:
everything is a file
。 參考
【1】
【2】
【3】
【4】
【5】
【6】 講的詳細
ie9 及其他相容placeholder
placeholder屬性樹html5提出的新屬性,作用是為input框或textarea框新增初始提示內容。當控制項獲取焦點輸入時,清空提示內容。但ie8及其以下的版本並不支援該屬性的顯示。下面做如下處理 placeholder屬性樹html5提出的新屬性,作用是為input框或textarea框...
Linux常用命令 9 其他命令
命令 功能命令 功能echo 顯示一字串 passwd 修改密碼 clear 清除顯示器 lpr列印 lpq檢視在列印佇列中等待的作業 lprm 取消列印佇列中的作業 9.1 echo命令 echo命令用來在顯示器上輸出一段文字,這個命令常用來輸出一些提示資訊,因此這個命令的意義在於輸出一些文字。它...
9 學習Lucene3 5索引搜尋之其他搜尋
1 lucene3.5索引搜尋之字首搜尋 lucene搜尋之prefixquery 字首搜尋 public void searchbyprefixquery string field,string value 2 lucene3.5索引搜尋之萬用字元搜尋 lucene搜尋之prefixquery 萬...