1、select
呼叫select發生以下事情:
1)從使用者空間複製fd_set到核心空間;
2)註冊回撥函式_pollwait;
3)遍歷所有的fd,對全部指定的裝置做一次poll(poll指一個檔案操作,有兩個引數,一個是檔案fd本身,一個是當裝置尚未就緒時呼叫的回撥函式,這個函式將裝置自己特有的等待佇列傳給核心,讓核心把當前程序掛載到其中)。
4)裝置就緒就喚醒自己特有等待佇列中的所有節點,當前執行緒獲得完成訊號;
5)所有裝置的掩碼都木有顯示任何事件觸發,就去回撥函式指標,進入睡眠,再恢復進行poll,再休眠,直到事件觸發為止。
6)只要有事件觸發,系統呼叫返回,將fd_set從核心空間複製到使用者空間,回到使用者態,使用者就可以對相關的fd做進一步的讀或者寫操作;
2、epoll
呼叫epoll_create做下面事情:
1)核心幫我們再epoll檔案系統建立了file結點;
2)在核心cache裡建紅黑樹用於儲存epoll_ctl傳來的socket;
3)建立list連結串列,用於儲存準備就緒的事件;
呼叫epoll_ctl:
1)把socket放到epoll檔案系統裡file物件對應的紅黑樹;
2)給核心中斷處理程式註冊一個回撥函式,告訴核心,中斷了,放到就緒list連結串列裡面;
呼叫epoll_wait:
list連結串列是否有資料,有資料就返回,木有資料就sleep,等到timeout即使木有資料也返回。
兩者比較:
1)select
併發數限制:使用32位整數標識fd,即32*32=1024;
效率低:每次都會線性掃描整個fd_set,集合大,速度慢;
核心/使用者空間記憶體複製問題;
2) epoll
沒有最大併發限制,僅受系統中程序能開啟的最大檔案數目限制;
效率更高,只有活躍的socket才會主動呼叫callback函式;
省去記憶體複製;
1、select
呼叫select發生以下事情:
1)從使用者空間複製fd_set到核心空間;
2)註冊回撥函式_pollwait;
3)遍歷所有的fd,對全部指定的裝置做一次poll(poll指一個檔案操作,有兩個引數,一個是檔案fd本身,一個是當裝置尚未就緒時呼叫的回撥函式,這個函式將裝置自己特有的等待佇列傳給核心,讓核心把當前程序掛載到其中)。
4)裝置就緒就喚醒自己特有等待佇列中的所有節點,當前執行緒獲得完成訊號;
5)所有裝置的掩碼都木有顯示任何事件觸發,就去回撥函式指標,進入睡眠,再恢復進行poll,再休眠,直到事件觸發為止。
6)只要有事件觸發,系統呼叫返回,將fd_set從核心空間複製到使用者空間,回到使用者態,使用者就可以對相關的fd做進一步的讀或者寫操作;
2、epoll
呼叫epoll_create做下面事情:
1)核心幫我們再epoll檔案系統建立了file結點;
2)在核心cache裡建紅黑樹用於儲存epoll_ctl傳來的socket;
3)建立list連結串列,用於儲存準備就緒的事件;
呼叫epoll_ctl:
1)把socket放到epoll檔案系統裡file物件對應的紅黑樹;
2)給核心中斷處理程式註冊一個回撥函式,告訴核心,中斷了,放到就緒list連結串列裡面;
呼叫epoll_wait:
list連結串列是否有資料,有資料就返回,木有資料就sleep,等到timeout即使木有資料也返回。
兩者比較:
1)select
併發數限制:使用32位整數標識fd,即32*32=1024;
效率低:每次都會線性掃描整個fd_set,集合大,速度慢;
核心/使用者空間記憶體複製問題;
2) epoll
沒有最大併發限制,僅受系統中程序能開啟的最大檔案數目限制;
效率更高,只有活躍的socket才會主動呼叫callback函式;
省去記憶體複製;