• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

               C++ 技術中心

               :: 首頁 :: 聯系 ::  :: 管理
              160 Posts :: 0 Stories :: 87 Comments :: 0 Trackbacks

            公告

            鄭重聲明:本BLOG所發表的原創文章,作者保留一切權利。必須經過作者本人同意后方可轉載,并注名作者(天空)和出處(CppBlog.com)。作者Email:coder@luckcoder.com

            留言簿(27)

            搜索

            •  

            最新隨筆

            最新評論

            評論排行榜

            epoll調用

            在linux的網絡編程中,很長的時間都在使用select來做事件觸發。在linux新的內核中,有了一種替換它的機制,就是epoll。
            相比于select,epoll最大的好處在于它不會隨著監聽fd數目的增長而降低效率。因為在內核中的select實現中,它是采用輪詢來處理的,輪詢的fd數目越多,自然耗時越多。并且,在linux/posix_types.h頭文件有這樣的聲明:
            #define __FD_SETSIZE 1024
            表示select最多同時監聽1024個fd,當然,可以通過修改頭文件再重編譯內核來擴大這個數目,但這似乎并不治本。

            epoll的接口非常簡單,一共就三個函數:
            1. int epoll_create(int size);
            創建一個epoll的句柄,size用來告訴內核這個監聽的數目一共有多大。這個參數不同于select()中的第一個參數,給出最大監聽的fd+1的值。需要注意的是,當創建好epoll句柄后,它就是會占用一個fd值,在linux下如果查看/proc/進程id/fd/,是能夠看到這個fd的,所以在使用完epoll后,必須調用close()關閉,否則可能導致fd被耗盡。


            2. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
            epoll的事件注冊函數,它不同與select()是在監聽事件時告訴內核要監聽什么類型的事件,而是在這里先注冊要監聽的事件類型。第一個參數是epoll_create()的返回值,第二個參數表示動作,用三個宏來表示:
            EPOLL_CTL_ADD:注冊新的fd到epfd中;
            EPOLL_CTL_MOD:修改已經注冊的fd的監聽事件;
            EPOLL_CTL_DEL:從epfd中刪除一個fd;
            第三個參數是需要監聽的fd,第四個參數是告訴內核需要監聽什么事,struct epoll_event結構如下:
            struct epoll_event {
            __uint32_t events; /* Epoll events */
            epoll_data_t data; /* User data variable */
            };

            events可以是以下幾個宏的集合:
            EPOLLIN :表示對應的文件描述符可以讀(包括對端SOCKET正常關閉);
            EPOLLOUT:表示對應的文件描述符可以寫;
            EPOLLPRI:表示對應的文件描述符有緊急的數據可讀(這里應該表示有帶外數據到來);
            EPOLLERR:表示對應的文件描述符發生錯誤;
            EPOLLHUP:表示對應的文件描述符被掛斷;
            EPOLLET: 將EPOLL設為邊緣觸發(Edge Triggered)模式,這是相對于水平觸發(Level Triggered)來說的。
            EPOLLONESHOT:只監聽一次事件,當監聽完這次事件之后,如果還需要繼續監聽這個socket的話,需要再次把這個socket加入到EPOLL隊列里


            3. int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
            等待事件的產生,類似于select()調用。參數events用來返回從內核得到事件的集合,maxevents告之內核這個events有多大,這個maxevents的值不能大于創建epoll_create()時的size,參數timeout是超時時間(毫秒,0會立即返回,-1將不確定,也有說法說是永久阻塞)。該函數返回需要處理的事件數目,如返回0表示已超時。

            使用epoll的注意事項
            1. ET模式比LT模式高效,但比較難控制。
            2. 如果某個句柄期待的事件不變,不需要EPOLL_CTL_MOD,但每次讀寫后將該句柄modify一次有助于提高穩定性,特別在ET模式。
            3. socket關閉后最好將該句柄從epoll中delete(EPOLL_CTL_DEL),雖然epoll自身有處理,但會使epoll的hash的節點數增多,影響搜索hash的速度。
            posted on 2013-07-01 14:35 C++技術中心 閱讀(1488) 評論(0)  編輯 收藏 引用 所屬分類: Linux 編程
            久久精品国产亚洲AV久| 久久久久国产亚洲AV麻豆| 亚洲精品高清一二区久久| 99久久国产综合精品麻豆| 精品久久人人做人人爽综合 | 99久久99久久| 国产精自产拍久久久久久蜜| 亚洲午夜久久久久妓女影院| 伊人久久大香线蕉精品不卡 | 色诱久久久久综合网ywww| 国产精品99久久精品爆乳| 2020国产成人久久精品| 久久久久亚洲AV成人网人人软件 | 免费一级做a爰片久久毛片潮| 亚洲国产精品无码成人片久久| 久久综合色老色| 久久亚洲高清综合| 久久国产精品-久久精品| 久久精品国产精品亚洲毛片| 日韩人妻无码精品久久免费一| 久久WWW免费人成—看片| 97久久久久人妻精品专区| 久久无码国产专区精品| 亚洲精品美女久久久久99小说 | 97久久精品人人澡人人爽| 精品久久久久中文字| 色综合久久综合中文综合网| 综合久久一区二区三区 | 久久久久久亚洲AV无码专区| 亚洲欧美成人久久综合中文网 | 亚洲色婷婷综合久久| 漂亮人妻被中出中文字幕久久 | 亚洲va中文字幕无码久久| 中文字幕无码久久人妻| 色综合久久久久综合99| 久久精品国产2020| 无码八A片人妻少妇久久| 综合久久国产九一剧情麻豆| 伊人久久综合无码成人网 | 热99re久久国超精品首页| 一本大道久久香蕉成人网|