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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

libevent源码深度剖析十

發布時間:2023/12/19 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 libevent源码深度剖析十 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

libevent源碼深度剖析十

——支持I/O多路復用技術
張亮

????? Libevent的核心是事件驅動、同步非阻塞,為了達到這一目標,必須采用系統提供的I/O多路復用技術,而這些在Windows、Linux、 Unix等不同平臺上卻各有不同,如何能提供優雅而統一的支持方式,是首要關鍵的問題,這其實不難,本節就來分析一下。

1 統一的關鍵

????? Libevent支持多種I/O多路復用技術的關鍵就在于結構體eventop,這個結構體前面也曾提到過,它的成員是一系列的函數指針, 定義在event-internal.h文件中:

[cpp] view plaincopy
  • struct?eventop?{??
  • ????const?char?*name;??
  • ????void?*(*init)(struct?event_base?*);?//?初始化??
  • ????int?(*add)(void?*,?struct?event?*);?//?注冊事件??
  • ????int?(*del)(void?*,?struct?event?*);?//?刪除事件??
  • ????int?(*dispatch)(struct?event_base?*,?void?*,?struct?timeval?*);?//?事件分發??
  • ????void?(*dealloc)(struct?event_base?*,?void?*);?//?注銷,釋放資源??
  • ????/*?set?if?we?need?to?reinitialize?the?event?base?*/??
  • ????int?need_reinit;??
  • };??

  • ????? 在libevent中,每種I/O demultiplex機制的實現都必須提供這五個函數接口,來完成自身的初始化、銷毀釋放;對事件的注冊、注銷和分發。
    比如對于epoll,libevent實現了5個對應的接口函數,并在初始化時并將eventop的5個函數指針指向這5個函數,那么程序就可以使用epoll作為I/O demultiplex機制了。

    2 設置I/O demultiplex機制

    ????? Libevent把所有支持的I/O demultiplex機制存儲在一個全局靜態數組eventops中,并在初始化時選擇使用何種機制,數組內容根據優先級順序聲明如下:

    [cpp] view plaincopy
  • /*?In?order?of?preference?*/??
  • static?const?struct?eventop?*eventops[]?=?{??
  • #ifdef?HAVE_EVENT_PORTS??
  • ????&evportops,??
  • #endif??
  • #ifdef?HAVE_WORKING_KQUEUE??
  • ????&kqops,??
  • #endif??
  • #ifdef?HAVE_EPOLL??
  • ????&epollops,??
  • #endif??
  • #ifdef?HAVE_DEVPOLL??
  • ????&devpollops,??
  • #endif??
  • #ifdef?HAVE_POLL??
  • ????&pollops,??
  • #endif??
  • #ifdef?HAVE_SELECT??
  • ????&selectops,??
  • #endif??
  • #ifdef?WIN32??
  • ????&win32ops,??
  • #endif??
  • ????NULL??
  • };???

  • ???? 然后libevent根據系統配置和編譯選項決定使用哪一種I/O demultiplex機制,這段代碼在函數event_base_new()中:

    [cpp] view plaincopy
  • base->evbase?=?NULL;??
  • ????for?(i?=?0;?eventops[i]?&&?!base->evbase;?i++)?{??
  • ????????base->evsel?=?eventops[i];??
  • ????????base->evbase?=?base->evsel->init(base);??
  • ????}???

  • ??? 可以看出,libevent在編譯階段選擇系統的I/O demultiplex機制,而不支持在運行階段根據配置再次選擇。
    ??? 以Linux下面的epoll為例,實現在源文件epoll.c中,eventops對象epollops定義如下:

    [cpp] view plaincopy
  • const?struct?eventop?epollops?=?{??
  • ????"epoll",??
  • ????epoll_init,??
  • ????epoll_add,??
  • ????epoll_del,??
  • ????epoll_dispatch,??
  • ????epoll_dealloc,??
  • ????1?/*?need?reinit?*/??
  • };??

  • 變量epollops中的函數指針具體聲明如下,注意到其返回值和參數都和eventop中的定義嚴格一致,這是函數指針的語法限制。

    [cpp] view plaincopy
  • static?void?*epoll_init????(struct?event_base?*);??
  • static?int?epoll_add????(void?*,?struct?event?*);??
  • static?int?epoll_del????(void?*,?struct?event?*);??
  • static?int?epoll_dispatch(struct?event_base?*,?void?*,?struct?timeval?*);??
  • static?void?epoll_dealloc????(struct?event_base?*,?void?*);??

  • ????? 那么如果選擇的是epoll,那么調用結構體eventop的init和dispatch函數指針時,實際調用的函數就是epoll的初始化函數epoll_init()和事件分發函數epoll_dispatch()了;
    ???? 關于epoll的具體用法這里就不多說了,可以參見介紹epoll的文章(本人的哈哈):
    http://blog.csdn.net/sparkliang/archive/2009/11/05/4770655.aspx


    ???? C++語言提供了虛函數來實現多態,在C語言中,這是通過函數指針實現的。對于各類函數指針的詳細說明可以參見文章:
    http://blog.csdn.net/sparkliang/archive/2009/06/09/4254115.aspx
    同樣的,上面epollops以及epoll的各種函數都直接定義在了epoll.c源文件中,對外都是不可見的。對于libevent的使用者而言,完全不會知道它們的存在,對epoll的使用也是通過eventop來完成的,達到了信息隱藏的目的。

    3 小節

    ??? 支持多種I/O demultiplex機制的方法其實挺簡單的,借助于函數指針就OK了。通過對源代碼的分析也可以看出,Libevent是在編譯階段選擇系統的I/O demultiplex機制的,而不支持在運行階段根據配置再次選擇。

    轉載于:https://www.cnblogs.com/breg/p/3725762.html

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的libevent源码深度剖析十的全部內容,希望文章能夠幫你解決所遇到的問題。

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