日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

select poll 与epoll模型的总结

發布時間:2024/4/11 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 select poll 与epoll模型的总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

select()和poll() IO多路復用模型

select優點:
1.一次可以等待多個文件描述符,減少了平均等待時間
2.客戶越來越多時,減輕了進程調度的壓力(相較于多進程多線程服務器)
select缺點:
1.能監聽的文件描述符有上限,這個上限是由fd_set決定的。
2.它返回的只是就緒事件的個數,要判斷是那個事件滿足,需要遍歷文件描述符。
3.select監聽的集合是輸入輸出參數,每次監聽都需要重新初始化。
4.每次調用select,都需要把fd集合從用戶態拷貝到內核態,這個開銷在fd很多時會很大
5.內核采用輪詢(遍歷fd集合)的方式來檢測就緒事件,這個開銷在fd很多時也很大
6.select和poll都只能工作在低效的LT(水平觸發)模式
poll優點:
1.poll監聽的文件描述符沒有最大數量的限制
2.poll對于select來說包含了一個pollfd結構,pollfd結構包含了要監視的event和發生的revent,而不像select那樣使用輸入輸出的傳遞方式。所以不需要每次監聽都初始化
poll缺點:
1.數量過大以后其效率也會線性下降。
2.poll和select一樣也是返回就緒事件的個數,需要遍歷文件描述符來判斷是那個事件已經就緒,當數量很大時,開銷也就很大。
3.select和poll都只能工作在低效的LT(水平觸發)模式
4.每次調用poll,都需要把pollfd數組從用戶態拷貝到內核態,這個開銷在fd很多時會很大
5.內核采用輪詢(遍歷pollfd數組)的方式來檢測就緒事件,這個開銷在fd很多時也很大

拿select模型為例,假設我們的服務器需要支持100萬的并發連接,則在__FD_SETSIZE 為1024的情況下,則我們至少需要開辟1k個進程才能實現100萬的并發連接。除了進程間上下文切換的時間消耗外,從內核/用戶空間大量的無腦內存拷貝、數組輪詢等,是系統難以承受的。因此,基于select模型的服務器程序,要達到10萬級別的并發訪問,是一個很難完成的任務。

因此,該epoll上場了。

epoll IO多路復用模型實現機制

由于epoll的實現機制與select/poll機制完全不同,上面所說的?select的缺點在epoll上不復存在。

設想一下如下場景:有100萬個客戶端同時與一個服務器進程保持著TCP連接。而每一時刻,通常只有幾百上千個TCP連接是活躍的(事實上大部分場景都是這種情況)。如何實現這樣的高并發?

在select/poll時代,服務器進程每次都把這100萬個連接告訴操作系統(從用戶態復制句柄數據結構到內核態),讓操作系統內核去查詢這些套接字上是否有事件發生,輪詢完后,再將句柄數據復制到用戶態,讓服務器應用程序輪詢處理已發生的網絡事件,這一過程資源消耗較大,因此,select/poll一般只能處理幾千的并發連接。

epoll的設計和實現與select完全不同。epoll通過在Linux內核中申請一個簡易的文件系統(文件系統一般用什么數據結構實現?紅黑樹)。把原先的select/poll調用分成了3個部分:

1)調用epoll_create()建立一個epoll對象(在epoll文件系統中為這個句柄對象分配資源)

2)調用epoll_ctl向epoll對象中添加這100萬個連接的套接字

3)調用epoll_wait收集發生的事件的連接

如此一來,要實現上面說是的場景,只需要在進程啟動時建立一個epoll對象,然后在需要的時候向這個epoll對象中添加或者刪除連接。同時,epoll_wait的效率也非常高,因為調用epoll_wait時,并沒有一股腦的向操作系統復制這100萬個連接的句柄數據,內核也不需要去遍歷全部的連接。

下面來看看linux內核具體的epoll機制實現思路。

當某一進程調用epoll_create方法時,Linux內核會創建一個eventpoll結構體,這個結構體中有兩個成員與epoll的使用方式密切相關。eventpoll結構體如下所示:

[cpp]?view plaincopy
  • struct?eventpoll{??
  • ????....??
  • ????/*紅黑樹的根節點,這顆樹中存儲著所有添加到epoll中的需要監控的事件*/??
  • ????struct?rb_root??rbr;??
  • ????/*雙鏈表中則存放著將要通過epoll_wait返回給用戶的滿足條件的事件*/??
  • ????struct?list_head?rdlist;??
  • ????....??
  • };??
  • 每一個epoll對象都有一個獨立的eventpoll結構體,用于存放通過epoll_ctl方法向epoll對象中添加進來的事件。這些事件都會掛載在紅黑樹中,如此,重復添加的事件就可以通過紅黑樹而高效的識別出來(紅黑樹的插入時間效率是lgn,其中n為樹的高度)。

    而所有添加到epoll中的事件都會與設備(網卡)驅動程序建立回調關系,也就是說,當相應的事件發生時會調用這個回調方法。這個回調方法在內核中叫ep_poll_callback,它會將發生的事件添加到rdlist雙鏈表中。

    在epoll中,對于每一個事件,都會建立一個epitem結構體,如下所示:

    [cpp]?view plaincopy
  • struct?epitem{??
  • ????struct?rb_node??rbn;//紅黑樹節點??
  • ????struct?list_head????rdllink;//雙向鏈表節點??
  • ????struct?epoll_filefd??ffd;??//事件句柄信息??
  • ????struct?eventpoll?*ep;????//指向其所屬的eventpoll對象??
  • ????struct?epoll_event?event;?//期待發生的事件類型??
  • }??
  • 當調用epoll_wait檢查是否有事件發生時,只需要檢查eventpoll對象中的rdlist雙鏈表中是否有epitem元素即可。如果rdlist不為空,則把發生的事件復制到用戶態,同時將事件數量返回給用戶。

    epoll數據結構示意圖

    從上面的講解可知:通過紅黑樹和雙鏈表數據結構,并結合回調機制,造就了epoll的高效。

    OK,講解完了Epoll的機理,我們便能很容易掌握epoll的用法了。一句話描述就是:三步曲。

    第一步:epoll_create()系統調用。此調用返回一個句柄,之后所有的使用都依靠這個句柄來標識。

    第二步:epoll_ctl()系統調用。通過此調用向epoll對象中添加、刪除、修改感興趣的事件,返回0標識成功,返回-1表示失敗。

    第三部:epoll_wait()系統調用。通過此調用收集收集在epoll監控中已經發生的事件。

    epoll優點:
    1.epoll維護的描述符數目不受到限制,而且性能不會隨著描述符數目的增加而下降。(不需要遍歷整個文件描述符)
    2.epoll先通過epoll_ctl注冊一個描述符到內核中,并一直維護著而不像poll每次操作都將所有要監控的描述符傳遞給內核
    3.在描述符讀寫就緒時,通過回掉函數將自己加入就緒隊列中,之后epoll_wait返回該就緒隊列,所以用戶不需要遍歷整個文件描述符判斷哪些事件就緒。性能提升。
    4.支持ET高效模式。

    poll和select適用于關心描述符個數多的應用程序。其中epoll對于每次只有很少描述符就緒很有優勢(采用回調機制監測描述符就緒)。

    總結

    以上是生活随笔為你收集整理的select poll 与epoll模型的总结的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。