您好,登錄后才能下訂單哦!
IO的多路復用:一個進程可以監視多個描述符,一旦某個描述符讀就緒或寫就緒,能夠通知進程程序進行相應的讀寫操作
使用場景:
1.當客戶處理多個描述符(網絡套接口)或一個客戶同時處理多個套接口
2.TCP服務器既要處理監聽套接口又要處理已經連接的套接口
3.一個服務器處理多個服務或多個協議也要使用I/O復用
與多進程和多線程相比,I/O多路復用最大優點系統開銷小,系統也不必創建進程或線程,因而也不用維護這些進程和線程
支持I/O多路復用的系統調用:select、poll、epoll本質上都是同步IO,因此它們都要在讀寫事件就緒后自己負責讀寫
1.select
基本原理:該函數監視的文件描述符分讀描述符集、寫描述符集、異常描述符集,調用該函數后select就會一直阻塞等待,直到有描述符就緒(至少有一個),或者超時等待
優點:具有良好的跨平臺性
缺點:
1.單個進程所打開文件描述符個數有數量限制,32位平臺下默認1024,64位平臺下默認2048
2.每次都要對sock集進行線性掃描(輪詢)每次都要從用戶態切換到內核態,需要的開銷大
3.需要維護一個用來存放大量描述符的數據結構(數組),在內核和用戶空間之間的傳遞復制開銷也很大
4.每次調用select函數前都要對timeout進行初始化,還要對它所關心的文件描述符所在的描述符集進行初始化工作
select中的timeout結構體:
1.若傳NULL,就是將select設置為阻塞狀態,一定要等到一個或多個描述符狀態發生變化
2.若設為0秒0毫秒,則變為一個非阻塞函數,不管描述符狀態是否發生變化都立即返回
3.若設為大于0,則函數會在timeout時間內阻塞,超時時間內若有事件到來就返回
2.poll
基本原理:將用戶傳入的數組拷貝到內核區,輪詢查看每個描述符對應的事件狀態,若事件就緒就加入等待隊列中繼續遍歷,若遍歷結束沒有事件就緒,就掛起進程,直到有就緒事件到達或超時被喚醒,之后又要輪詢
poll中含有一個結構體,它包含了要監視的事件和發生的事件,不在使用select中的參數值傳遞方式。
優點:沒有最大連接數的限制,因為它基于鏈表來存儲
水平觸發,在每次調用該函數時都會再次檢測該socket來查看該socket緩沖區中的數據是否已被讀完
缺點:
1.在每次調用該函數后都要輪詢遍歷描述符來獲取就緒的socket
2.當同時連接大量客戶端時,而在某一時刻可能只有很少的處于就緒狀態,隨著監視的描述符數量增長,它的效率也會降低
適用場景:連接數量少并且每個連接都十分活躍
3.epoll:使用一個描述符來管理多個描述符,將用戶所關心的描述符相應事件存放到內核的事件表上,只需拷貝一次
使用三個函數:
epoll_create創建一個epollfd
epoll_ctl進行注冊某個socket描述符
epoll_wait等待就緒事件
基本原理:支持水平觸發和邊緣觸發,一般默認水平觸發,當使用邊緣觸發時,只告訴進程哪些描述符已經變為就緒狀態并且只通知一次。會先注冊所要關心的文件描述符及它所關心的事件,內核也會采用相應的回調機制來激活該描述符,使用epoll_wait只返回就緒的事件
優點:
1.沒有最大并發連接的限制,不需要輪詢的方式每次都要遍歷描述符集,不會隨著描述符數目的增加而下降
2.使用mmap(內存映射技術)加速與內核之間的消息傳遞,減少了從用戶到內存的拷貝次數
,不同于select和poll的消息傳遞方式,通過內核與用戶空間共享一塊內存來實現
兩種工作模式:
LT:當調用epoo_wait檢測到描述符事件發生并通知應用程序,應用程序應立即處理,若不處理,則下次還會再次告知上層應用程序
ET:調用epoll_wait檢測到描述符事件發生并通知上層應用且只通知一次,只支持非阻塞socket(避免由于一個句柄的阻塞讀或寫讓后續的多個文件描述符一直阻塞等待),在很大程度上減少了時間被重復觸發的次數
適用場景:同時處理大量客戶端同時請求連接服務器
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。