系統調用說明
epoll_create:在內核中創建epoll結構
epoll_ctl:add
1. 調用監聽的文件的poll方法,設置callback
2. 設備就緒時喚醒等待隊列上的進程,此時會調用callback
3. 該callback會將監聽事件放入epoll的就緒隊列中
epoll_wait:判斷就緒隊列中是否有事件
與select, poll區別
select/poll 會將監聽的描述符表copy到內核
然后順序掃描各個監聽對象的poll函數,如果有事件(如可讀),poll返回可讀掩碼。
循環最后如果有事件就返回用戶空間進行處理
ET為啥比LT高效?
更少的系統調用次數?
ET飢餓現象如何避免?
飢餓:如某個鏈接上有大量數據寫入,導致其他事件得不到處理。
可以在用戶態做一層管理,如果讀取了1MB以上的數據,就處理下一個事件。均衡一下
select源碼
[fs/select.c do_select](https://www.jianshu.com/p/da6642369ef0)
如果沒有就緒事件就去睡眠,直到超時時間到,醒來再遍歷一把,然后timeout退出。
要么從timeout中醒來,要么從事件中醒來,醒來之后繼續在死循環中
poll會返回當前fd的狀態(比如是否可讀寫),根據這個狀態,do_select做不同的動作。
1. 如果fd的狀態與應用程序監聽的事件匹配,則記錄下來,do_select退出循環,並把結果返給上層。
2. 如果不匹配,do_select發現timeout或進程有signal信號打斷,也會退出循環,返回空給應用。
epoll部分源碼
ep_insert注冊的回調函數中,會把epitem放到eventpoll結構的rdlist上
ep_send_event中調用ep_send_events_proc的每個event,這里要調用epitem對應的file的poll函數,獲取返回的掩碼
void poll_wait(struct file *filp, wait_queue_head_t *queue, poll_table *wait);
他的作用就是把當前進程添加到wait參數指定的等待列表(poll_table)中。該函數中不會阻塞。
另一個函數:__wake_up_common