真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

epoll 函數(shù)解析

本文參考社長(zhǎng)的 TinyWebServer 庖丁解牛

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括灌南網(wǎng)站建設(shè)、灌南網(wǎng)站制作、灌南網(wǎng)頁(yè)制作以及灌南網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,灌南網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到灌南省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

epoll 常用API

epoll_create 函數(shù)

#include 
int epoll_create(int size);

創(chuàng)建一個(gè)指示 epoll 內(nèi)核事件表的文件描述符,該描述符將用作其他 epoll 系統(tǒng)調(diào)用的第一個(gè)參數(shù),此處的 size 參數(shù)不起作用。

epoll_ctl 函數(shù)

#include 
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

該函數(shù)用于操作內(nèi)核事件表監(jiān)控的文件描述符上的事件:注冊(cè)、修改、刪除:

  • epfd:為 epoll_create 的句柄;
  • op:表示動(dòng)作,用 3 個(gè)宏來(lái)表示:
    • EPOLL_CTL_ADD:注冊(cè)新的 fd 到 epfd;
    • EPOLL_CTL_MOD:修改已經(jīng)注冊(cè)的 fd 的監(jiān)聽(tīng)事件;
    • EPOLL_CTL_DEL:從 epfd 刪除一個(gè) fd;
  • event:告訴內(nèi)核需要監(jiān)聽(tīng)的事件。

其中,eventepoll_event 結(jié)構(gòu)體指針類(lèi)型,表示內(nèi)核監(jiān)聽(tīng)的事件,具體定義如下:

struct epoll_event {
    __uint32_t events;
    epoll_data_t data;
};
  • events 描述事件類(lèi)型,其中 epoll 事件類(lèi)型有以下幾種:
    • EPOLLIN:表示對(duì)應(yīng)的文件描述符可讀(包括對(duì)端SOCKET正常關(guān)閉)
    • EPOLLOUT:表示對(duì)應(yīng)的文件描述符可寫(xiě);
    • EPOLLPRI:表示對(duì)應(yīng)的文件描述符有緊急的數(shù)據(jù)可讀(這里應(yīng)該表示有帶外數(shù)據(jù)到來(lái))
    • EPOLLERR:表示對(duì)應(yīng)的文件描述符發(fā)生錯(cuò)誤;
    • EPOLLHUP:表示對(duì)應(yīng)的文件描述符被掛斷;
    • EPOLLLET:將 EPOLL 設(shè)置為邊緣觸發(fā)(ET)模式;
    • EPOLLONESHOT:只監(jiān)聽(tīng)一次事件,當(dāng)監(jiān)聽(tīng)完這次事件之后,如果還需要繼續(xù)監(jiān)聽(tīng)這個(gè) socket 的話,需要再次把這個(gè) socket 加入到 EPOLL 隊(duì)列中。

epoll_wait 函數(shù)

#include 
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

該函數(shù)用于等待所監(jiān)控的文件描述符上有事件的產(chǎn)生,返回就緒的文件描述符的個(gè)數(shù)。

  • events:用來(lái)存儲(chǔ)內(nèi)核得到的事件的集合;
  • maxevents:告知內(nèi)核這個(gè) events 有多大,這個(gè)值不能大于創(chuàng)建 epoll_create() 時(shí)的大?。?/li>
  • timeout:超時(shí)時(shí)間:
    • -1:阻塞;
    • 0:立即返回,非阻塞;
    • >0:指定毫秒數(shù);
  • 返回值:成功返回有多少文件描述符就緒,時(shí)間到時(shí)返回 0,出錯(cuò)時(shí)返回-1。

select/poll/epoll 的區(qū)別

  • 調(diào)用函數(shù)

    • select 和 poll 都是一個(gè)函數(shù),epoll 是一組函數(shù);
  • 文件描述符數(shù)量

    • select 使用線性表保存文件描述符的集合,文件描述符有上限,一般是 1024,但可以修改源碼,重新編譯內(nèi)核,不推薦;
    • poll 是使用鏈表存儲(chǔ)文件描述符的集合,突破了文件描述符的上限;
    • epoll 使用紅黑樹(shù)存儲(chǔ)文件描述符的集合,突破了文件描述符的上限(通過(guò)命令 ulimit -n number 修改,僅對(duì)當(dāng)前終端有效);
  • 將文件描述符從用戶傳給內(nèi)核:

    • select 和 poll 將所有文件描述符拷貝到內(nèi)核態(tài),每次調(diào)用都需要拷貝;
    • epoll 通過(guò) epoll_create 建立一棵紅黑樹(shù),通過(guò) epoll_ctl 將要監(jiān)聽(tīng)的文件描述符注冊(cè)到紅黑樹(shù)上,文件描述符都在內(nèi)核態(tài);
  • 內(nèi)核判斷就緒的文件描述符:

    • select 和 poll 通過(guò)遍歷文件描述符集合,判斷哪個(gè)文件描述符上有事件發(fā)生;
    • epoll_create 時(shí),內(nèi)核除了會(huì)建立一個(gè)紅黑樹(shù)來(lái)存儲(chǔ)以后 epoll_ctl 傳來(lái)的 fd 外,還會(huì)再建立一個(gè) list 鏈表,用于存儲(chǔ)準(zhǔn)備就緒的事件。當(dāng) epoll_wait 調(diào)用時(shí),僅僅觀察這個(gè) list 鏈表上有沒(méi)有數(shù)據(jù)即可;
    • epoll 是根據(jù)每個(gè) fd 上面的回調(diào)函數(shù)(中斷函數(shù))判斷,只有發(fā)生了時(shí)間的 socket 才會(huì)主動(dòng)的去調(diào)用 callback 函數(shù),其他空閑狀態(tài)的 socket 則不會(huì)。若是就緒事件,則插入 list;
  • 應(yīng)用程序索引就緒文件描述符:

    • select/epoll 只返回發(fā)生了事件的文件描述符的個(gè)數(shù),若想要知道哪些文件描述符發(fā)生了事件,需要再次遍歷;
    • epoll 返回的是發(fā)生了事件的個(gè)數(shù)和結(jié)構(gòu)體數(shù)組,結(jié)構(gòu)體包含 socket 的信息,因此直接處理返回的數(shù)組即可;
  • 工作模式:

    • select/poll 都只能工作在低效的 LT 模式下;
    • epoll 則可以工作在高效的 ET 模式,并且 epoll 還支持 EPOLLONESHOT 事件,可以進(jìn)一步減少可讀、可寫(xiě)和異常事件被觸發(fā)的次數(shù);

    其實(shí) ET 和 LT 哪個(gè)高效也是針對(duì)不同的任務(wù)而言。

  • 應(yīng)用場(chǎng)景:

    • 如果所有的 fd 都是活躍連接,epoll 需要建立紅黑樹(shù)和鏈表,效率反而不高,不如 select/epoll;
    • 如果監(jiān)測(cè)的 fd 數(shù)目較小,且各個(gè) fd 都比較活躍,建議使用 select/poll;
    • 如果監(jiān)測(cè)的 fd 數(shù)目非常大,并且單位時(shí)間內(nèi)只有其中一小部分 fd 處于就緒狀態(tài),這個(gè)時(shí)候使用 epoll 能夠明顯提升性能。

ET、LT、EPOLLONESHOT

  • LT 水平觸發(fā)模式

    • epoll_wait 檢測(cè)到文件描述符有事件發(fā)生,則將其通知給應(yīng)用程序,應(yīng)用程序可以不立即處理該事件;
    • 當(dāng)下一次調(diào)用 epoll_wait 時(shí),epoll_wait 還會(huì)再次向應(yīng)用程序報(bào)告此事件,直至被處理。

    Note:

    一個(gè)事件只要有,就會(huì)一直觸發(fā)。

    socket 上只要有未讀完的數(shù)據(jù),就會(huì)一直產(chǎn)生 EPOLLIN 事件。所以讀完數(shù)據(jù)要移除事件,避免一直觸發(fā)。

  • ET 邊緣觸發(fā)模式

    • epoll_wait 檢測(cè)到文件描述符有事件發(fā)生,則將其通知給應(yīng)用程序,應(yīng)用程序必須立即處理該事件;
    • 必須要一次性將數(shù)據(jù)讀取完,使用非阻塞 I/O,讀取到出現(xiàn) eagain。

    Note:

    只有一個(gè)事件從無(wú)到有,才會(huì)觸發(fā)。

    socket 上每新來(lái)一次數(shù)據(jù)就會(huì)觸發(fā)一次,如果某一次觸發(fā)后,未將 socket 上的數(shù)據(jù)全部讀完,也不會(huì)再次觸發(fā),除非再來(lái)一次數(shù)據(jù)。所以必須要一次性讀完所有數(shù)據(jù)。如果未讀完,需要再次將事件注冊(cè),

    ET 模式必須配合非阻塞 I/O 實(shí)現(xiàn),因?yàn)?ET 模式會(huì)一次性讀取完所有的數(shù)據(jù),如果是阻塞 I/O 的話,會(huì)導(dǎo)致線程阻塞,影響重新調(diào)用 epoll_wait 來(lái)監(jiān)聽(tīng)其他事件。


網(wǎng)站欄目:epoll 函數(shù)解析
本文地址:http://weahome.cn/article/dsoipjs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部