• <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++技術中心 閱讀(1497) 評論(0)  編輯 收藏 引用 所屬分類: Linux 編程
            欧美日韩成人精品久久久免费看| 欧美一区二区久久精品| 欧美一区二区三区久久综| 亚洲国产一成人久久精品| 亚洲va中文字幕无码久久不卡| 久久久久久国产精品无码超碰| 久久精品国产精品亚洲精品| 亚洲欧美国产日韩综合久久| avtt天堂网久久精品| 亚洲精品tv久久久久久久久久| 狠狠色丁香久久婷婷综| 久久久久久午夜精品| 99久久超碰中文字幕伊人| 热久久视久久精品18| 亚洲综合久久综合激情久久| 综合网日日天干夜夜久久| 国産精品久久久久久久| 久久国产免费观看精品| 香蕉久久夜色精品升级完成| 色综合久久久久综合99| 人人狠狠综合久久亚洲88| 久久婷婷五月综合色高清| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 久久午夜无码鲁丝片午夜精品| 波多野结衣AV无码久久一区| 久久国产乱子伦精品免费午夜| 久久精品国产亚洲AV香蕉| 一本久久免费视频| 色天使久久综合网天天| 久久精品国产精品亚洲人人 | 国产精品热久久无码av| 婷婷综合久久中文字幕蜜桃三电影| 久久中文字幕视频、最近更新| 品成人欧美大片久久国产欧美| 亚洲国产精品久久久久网站| 久久99国产精品二区不卡| 国产成人精品白浆久久69| 72种姿势欧美久久久久大黄蕉| 99久久777色| 色综合久久中文色婷婷| 国产精品久久久天天影视香蕉|