中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

IO多路復用--epoll

發布時間:2020-08-03 13:02:44 來源:網絡 閱讀:527 作者:馬尾和披肩 欄目:網絡安全

 epoll就是為了 處理大批量句柄而改進的poll,相比與select,poll最大的好處在于它不會隨著堅挺fd的數目增長而效率降低。因為在內核中的select是采用輪詢來處理的,輪詢fd的數目越多,自然耗時越多,并且slelct的監聽數目有限(雖然可以通過頭文件來改變,但并不治本)


一.epoll的相關系統調用  


epoll只有三個簡單地接口 分別為epoll_creat,epoll_ctl,epoll_wait

(1)int epoll_creat(int size)

   創建一個epoll句柄,當創建好一個epoll句柄后,它就會占一個 fd值,所以在使用完以后要調用close()函數關閉,否則fd可能被耗盡


(2)int epoll_ctl(int epfd,int op,int fd,struct epoll_event* event)

    epoll的事件注冊函數,它不同于 select函數在監聽事件的時候告訴內核要監聽什么類型的事件,而是 在 這里先注冊要監聽的事件類型

 第一個參數是epoll_creat的返回值

 第二個參數表示動作,用三個宏來表示 

 EPOLL_CTL_ADD:注冊新的fd到epfd中

EPOLL_CTL_MOD;修改已經注冊到的fd的監聽事件

EPOLL_CTL_DEL:從epfd中刪除一個fd

第三個參數 是 要監聽 的fd

第四個參數 告訴內核 需要監聽什么 事件


event可以是以下幾個 宏的集合

EPOLLIN:表示 對應的文件描述符可以讀(包括對socket正常關閉)

EPOLLOUT:表示 對應的文件描述符可以寫

EPOLLPRI:表示對應的文件描述符有緊急的數據可讀

EPOLLERR:對應的文件描述符發生錯誤

EPOLLET:將EPOLL設置為 邊沿除法模式 ,這是相對于水平觸發而言

EPOLLONESET:只監聽一次事件,如果之后還需要監聽的話,需要再次把這個socket鍵入到EPOLL隊列里


 

(3)int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout)

      收集epoll監控的事件中已經發生的事件參數event是分配好的epoll_event結構體數組。epoll把發生的事件賦值到events數組中 (events不可以是空指針,內核只負責把數據復制到數組中,但不會幫用戶開辟內存),maxevents告訴這個內核有多大這個maxevents的值不能大于創建的epoll_ctreat()時的size,闡述timeout是超時事件(毫秒 ,0立即返回,-1將不確定,也就是永久阻塞)如果函數調用成功,返回對應已準備好的文件描述符數目,如果返回0表示超時


二. epoll工作原理

epoll只告訴那些就緒的文件描述符,而且當你調用epoll_wait()獲得就緒文件描述符的時候,返回的不是實際的文件描述符,而是一個代表就緒描述符數量值你只是需要去epoll指定的一個數組 中一次獲得相應數量的文件描述符即可。


  另一個本質的改進在于epoll采用基于 事件的就緒通知方式,在select/poll中進程只有在調用一定的方法之后,內核才對所有監視的文件描述符進行掃描,而epoll先通過采用epoll_ctl()來注冊一個文件描述符,當進程調用epoll_wait()時便得到通知。


三. epoll的工作方式-水平觸發(LT)-邊沿觸發(ET)



LT(level triggered)是epoll缺省的工作方式,并且同時支持blockno-block socket.在這種做法中,內核告訴你一個文件描述符是否就緒了,然后你可以對這個就緒的fd進行IO操作。如果你不作任何操作,內核還是會繼續通知你 的,所以,這種模式編程出錯誤可能性要小一點。傳統的select/poll都是這種模型的代表.

 

ET (edge-triggered)是高速工作方式,只支持no-block socket,它效率要比LT更高。ET與LT的區別在于,當一個新的事件到來時,ET模式下當然可以從epoll_wait調用中獲取到這個事件,可是如果這次沒有把這個事件對應的套接字緩沖區處理完,在這個套接字中沒有新的事件再次到來時,在ET模式下是無法再次從epoll_wait調用中獲取這個事件的。而LT模式正好相反,只要一個事件對應的套接字緩沖區還有數據,就總能從epoll_wait中獲取這個事件。

因此,LT模式下開發基于epoll的應用要簡單些,不太容易出錯。而在ET模式下事件發生時,如果沒有徹底地將緩沖區數據處理完,則會導致緩沖區中的用戶請求得不到響應


四.epoll的優點


(1)支持一個進程打開大數目的socket描述符(FD)

select所能夠打開的fd是有限的一般為1024,對于那些支持上萬條鏈接數目的服務器來說 太少了,epoll就沒有這個限制 ,它所支持的FD上限是最大可以打開文件數目這個樹種子一般大于2048;

(2)IO效率不隨FD的數目 增加而線性下降

 傳統的select/poll致命弱點是當擁有一個很大的集合的時候,每次都用都會輪詢掃描 集合 ,導致效率下降,但是epoll只對活躍 的socket進行操作--因為在內核中epoll根據每個fd上面的callback函數實現的,只有活躍的函數 才會 調用 callback函數


五.linux下epoll如何處理百萬句柄


(1)首先調用epoll_creat建立一個epoll對象,參數 size是內核保證能夠正確處理的最大句柄數

(2)epoll_ctl操作上面建立好的epoll,例如讓剛建立的socket加入到epoll中讓其監控,或者把epoll正在監控的某個socke句柄移除epoll

(3)epoll_wait在給定的timeout時間內當監控的所有句柄發審核變化時就返回用戶態進程毫秒 ,0立即返回,-1將不確定,也就是永久阻塞)如果函數調用成功,返回對應已準備好的文件描述符數目,如果返回0表示超時


從上面調用方式可以看出epoll比select/poll的優越之處:因為 后者每次調用時都會給你返回所要監控所有socket給select/poll系統 調用 ,這意味著需要將用戶態的socket列表 拷貝到內核態,如果數以萬計的句柄會導致每次都要copy幾十幾百KB的內存到內核態,非常低效,但epoll_wait不用傳遞socket句柄給內核,因為內核已經在 epoll_ctl中拿到了要監控的句柄列表 


下面是代碼部分

1.創建監聽套接字,設置端口服用127.0.0.1 指定簇為 IPv4,指定端口號并 轉化為 網絡字節序列,指定ip地址并轉化為 網絡 字節序列 

IO多路復用--epoll


IO多路復用--epoll

2.調用epoll_creat得到一個epoll模型,判斷若創建成功,則調用epoll_ctl函數注冊要監聽事件的類型 ,本代碼中設置的監聽事件類型為EPOLLIN:表示 對應的文件描述符可以讀

 epoll的事件注冊函數,它不同于 select函數在監聽事件的時候告訴內核要監聽什么類型的事件,而是 在 這里先注冊要監聽的事件類型

 第一個參數是epoll_creat的返回值

 第二個參數表示動作,用三個宏來表示 

 EPOLL_CTL_ADD:注冊新的fd到epfd中

EPOLL_CTL_MOD;修改已經注冊到的fd的監聽事件

EPOLL_CTL_DEL:從epfd中刪除一個fd

第三個參數 是 要監聽 的fd

第四個參數 告訴內核 需要監聽什么 事件


event可以是以下幾個 宏的集合

EPOLLIN:表示 對應的文件描述符可以讀(包括對socket正常關閉)

EPOLLOUT:表示 對應的文件描述符可以寫

EPOLLPRI:表示對應的文件描述符有緊急的數據可讀

EPOLLERR:對應的文件描述符發生錯誤

EPOLLET:將EPOLL設置為 邊沿除法模式 ,這是相對于水平觸發而言

EPOLLONESET:只監聽一次事件,如果之后還需要監聽的話,需要再次把這個socket鍵入到EPOLL隊列里


IO多路復用--epoll

3.調用epoll_wait函數收集epoll監控的事件中已經發生的事件,參數event是分配好的epoll_event結構體數組。epoll把發生的事件賦值到events數組中 (events不可以是空指針,內核只負責把數據復制到數組中,但不會幫用戶開辟內存),maxevents告訴這個內核有多大這個maxevents的值不能大于創建的epoll_ctreat()時的size,

     闡述timeout是超時事件(毫秒 ,0立即返回,-1將不確定,也就是永久阻塞)如果函數調用成功,返回對應已準備好的文件描述符數目,如果返回0表示超時

      判斷它是否為 監聽套接字,如果是并且就緒  則對它進行接收,并且以邊沿出讓的方式讀入 ,若是其他套接字 ,則對他進行同樣的 接收

IO多路復用--epoll


IO多路復用--epoll

IO多路復用--epoll





向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

桦甸市| 依安县| 祁连县| 福建省| 金湖县| 高雄市| 凌云县| 伊春市| 乌兰县| 保康县| 兴义市| 西乌珠穆沁旗| 邢台县| 内江市| 五峰| 大连市| 宿迁市| 涟水县| 清丰县| 辛集市| 吴桥县| 甘南县| 台东县| 中超| 南开区| 大城县| 宝兴县| 泽普县| 安龙县| 峨眉山市| 改则县| 内乡县| 铜山县| 孝义市| 长治县| 彭山县| 东辽县| 镇巴县| 社会| 三明市| 炉霍县|