• <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>
            posts - 200, comments - 8, trackbacks - 0, articles - 0

            譯自http://www.wangafu.net/~nickm/libevent-book/Ref2_eventbase.html

            轉(zhuǎn)自:http://blog.sina.com.cn/s/blog_56dee71a0100qdxx.html 

            使用libevent函數(shù)之前需要分配一個或者多個event_base結(jié)構(gòu)體。每個event_base結(jié)構(gòu)體持有一個事件集合,可以檢測以確定哪個事件是激活的。

            如果設(shè)置event_base使用鎖,則可以安全地在多個線程中訪問它。然而,其事件循環(huán)只能運行在一個線程中。如果需要用多個線程檢測IO,則需要為每個線程使用一個event_base。

            每個event_base都有一種用于檢測哪種事件已經(jīng)就緒的“方法”,或者說后端。可以識別的方法有:

            v select

            v poll

            v epoll

            v kqueue

            v devpoll

            v evport

            v win32

            用戶可以用環(huán)境變量禁止某些特定的后端。比如說,要禁止kqueue后端,可以設(shè)置EVENT_NOKQUEUE環(huán)境變量。如果要用編程的方法禁止后端,請看下面關(guān)于event_config_avoid_method()的說明。

            1 建立默認的event_base

            event_base_new()函數(shù)分配并且返回一個新的具有默認設(shè)置的event_base。函數(shù)會檢測環(huán)境變量,返回一個到event_base的指針。如果發(fā)生錯誤,則返回NULL。選擇各種方法時,函數(shù)會選擇OS支持的最快方法。

            接口

            這個函數(shù)當前僅在Windows上使用IOCP時有用,雖然將來可能在其他平臺上有用。這個函數(shù)告訴event_config在生成多線程event_base的時候,應(yīng)該試圖使用給定數(shù)目的CPU。注意這僅僅是一個提示:event_base使用的CPU可能比你選擇的要少。

            示例


            struct event_base *event_base_new(void);

            大多數(shù)程序使用這個函數(shù)就夠了。

            event_base_new()函數(shù)聲明在<event2/event.h>中,首次出現(xiàn)在libevent 1.4.3版。

             

            2 創(chuàng)建復(fù)雜的event_base

            要對取得什么類型的event_base有更多的控制,就需要使用event_config。event_config是一個容納event_base配置信息的不透明結(jié)構(gòu)體。需要event_base時,將event_config傳遞給event_base_new_with_config()。

            2.1 接口

            struct event_config *event_config_new(void);
            struct event_base *event_base_new_with_config(const struct event_config *cfg);
            void event_config_free(struct event_config *cfg);

            要使用這些函數(shù)分配event_base,先調(diào)用event_config_new()分配一個event_config。然后,對event_config調(diào)用其它函數(shù),設(shè)置所需要的event_base特征。最后,調(diào)用event_base_new_with_config()獲取新的event_base。完成工作后,使用event_config_free()釋放event_config。

            2.2 接口

            int event_config_avoid_method(struct event_config *cfg, const char *method);

            enum event_method_feature {
                EV_FEATURE_ET 
            = 0x01,
                EV_FEATURE_O1 
            = 0x02,
                EV_FEATURE_FDS 
            = 0x04,
            };
            int event_config_require_features(struct event_config *cfg,
                                              
            enum event_method_feature feature);

            enum event_base_config_flag {
                EVENT_BASE_FLAG_NOLOCK 
            = 0x01,
                EVENT_BASE_FLAG_IGNORE_ENV 
            = 0x02,
                EVENT_BASE_FLAG_STARTUP_IOCP 
            = 0x04,
                EVENT_BASE_FLAG_NO_CACHE_TIME 
            = 0x08,
                EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST 
            = 0x10,
                EVENT_BASE_FLAG_PRECISE_TIMER 
            = 0x20
            };
            int event_config_set_flag(struct event_config *cfg,
                
            enum event_base_config_flag flag);

            調(diào)用event_config_avoid_method()可以通過名字讓libevent避免使用特定的可用后端。調(diào)用event_config_require_feature()讓libevent不使用不能提供所有指定特征的后端。調(diào)用event_config_set_flag()讓libevent在創(chuàng)建event_base時設(shè)置一個或者多個將在下面介紹的運行時標志。

            event_config_require_features()可識別的特征值有

            v EV_FEATURE_ET:要求支持邊沿觸發(fā)的后端

            v EV_FEATURE_O1:要求添加、刪除單個事件,或者確定哪個事件激活的操作是O(1)復(fù)雜度的后端

            v EV_FEATURE_FDS:要求支持任意文件描述符,而不僅僅是套接字的后端

            event_config_set_flag()可識別的選項值有

            v EVENT_BASE_FLAG_NOLOCK:不要為event_base分配鎖。設(shè)置這個選項可以為event_base節(jié)省一點用于鎖定和解鎖的時間,但是讓在多個線程中訪問event_base成為不安全的。

            v EVENT_BASE_FLAG_IGNORE_ENV:選擇使用的后端時,不要檢測EVENT_*環(huán)境變量。使用這個標志需要三思:這會讓用戶更難調(diào)試你的程序與libevent的交互。

            v EVENT_BASE_FLAG_STARTUP_IOCP:僅用于Windows,讓libevent在啟動時就啟用任何必需的IOCP分發(fā)邏輯,而不是按需啟用。

            v EVENT_BASE_FLAG_NO_CACHE_TIME:不是在事件循環(huán)每次準備執(zhí)行超時回調(diào)時檢測當前時間,而是在每次超時回調(diào)后進行檢測。注意:這會消耗更多的CPU時間。

            v EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST:告訴libevent,如果決定使用epoll后端,可以安全地使用更快的基于changelist的后端。epoll-changelist后端可以在后端的分發(fā)函數(shù)調(diào)用之間,同樣的fd多次修改其狀態(tài)的情況下,避免不必要的系統(tǒng)調(diào)用。但是如果傳遞任何使用dup()或者其變體克隆的fd給libevent,epoll-changelist后端會觸發(fā)一個內(nèi)核bug,導(dǎo)致不正確的結(jié)果。在不使用epoll后端的情況下,這個標志是沒有效果的。也可以通過設(shè)置EVENT_EPOLL_USE_CHANGELIST環(huán)境變量來打開epoll-changelist選項。

            上述操作event_config的函數(shù)都在成功時返回0,失敗時返回-1。

            注意

            設(shè)置event_config,請求OS不能提供的后端是很容易的。比如說,對于libevent 2.0.1-alpha,在Windows中是沒有O(1)后端的;在Linux中也沒有同時提供EV_FEATURE_FDS和EV_FEATURE_O1特征的后端。如果創(chuàng)建了libevent不能滿足的配置,event_base_new_with_config()會返回NULL。

            2.3 接口

            int event_config_set_num_cpus_hint(struct event_config *cfg, int cpus)

            這個函數(shù)當前僅在Windows上使用IOCP時有用,雖然將來可能在其他平臺上有用。這個函數(shù)告訴event_config在生成多線程event_base的時候,應(yīng)該試圖使用給定數(shù)目的CPU。注意這僅僅是一個提示:event_base使用的CPU可能比你選擇的要少。

            示例

            struct event_config *cfg;
            struct event_base *base;
            int i;

            /* My program wants to use edge-triggered events if at all possible.  So
               I'll try to get a base twice: Once insisting on edge-triggered IO, and
               once not. 
            */
            for (i=0; i<2++i) {
                cfg 
            = event_config_new();

                
            /* I don't like select. */
                event_config_avoid_method(cfg, 
            "select");

                
            if (i == 0)
                    event_config_require_features(cfg, EV_FEATURE_ET);

                
            base = event_base_new_with_config(cfg);
                event_config_free(cfg);
                
            if (base)
                    
            break;

                
            /* If we get here, event_base_new_with_config() returned NULL.  If
                   this is the first time around the loop, we'll try again without
                   setting EV_FEATURE_ET.  If this is the second time around the
                   loop, we'll give up. 
            */
            }

            這些函數(shù)和類型在<event2/event.h>中聲明。

            EVENT_BASE_FLAG_IGNORE_ENV標志首次出現(xiàn)在2.0.2-alpha版本。event_config_set_num_cpus_hint()函數(shù)是2.0.7-rc版本新引入的。本節(jié)的其他內(nèi)容首次出現(xiàn)在2.0.1-alpha版本。

            3 檢查event_base的后端方法

            有時候需要檢查event_base支持哪些特征,或者當前使用哪種方法。


            3.1 接口

            const char **event_get_supported_methods(void);

            event_get_supported_methods()函數(shù)返回一個指針,指向libevent支持的方法名字數(shù)組。這個數(shù)組的最后一個元素是NULL。

            示例

            int i;
            const char **methods = event_get_supported_methods();
            printf(
            "Starting Libevent %s.  Available methods are:\n",
                event_get_version());
            for (i=0; methods[i] != NULL; ++i) {
                printf(
            "    %s\n", methods[i]);
            }

            注意

            這個函數(shù)返回libevent被編譯以支持的方法列表。然而libevent運行的時候,操作系統(tǒng)可能不能支持所有方法。比如說,可能OS X版本中的kqueue的bug太多,無法使用。

            3.2 接口

            const char *event_base_get_method(const struct event_base *base);
            enum event_method_feature event_base_get_features(const struct event_base *base);

            event_base_get_method()返回event_base正在使用的方法。event_base_get_features()返回event_base支持的特征的比特掩碼。

            示例

            struct event_base *base;
            enum event_method_feature f;

            base = event_base_new();
            if (!base) {
                puts(
            "Couldn't get an event_base!");
            else {
                printf(
            "Using Libevent with backend method %s.",
                    event_base_get_method(
            base));
                f 
            = event_base_get_features(base);
                
            if ((f & EV_FEATURE_ET))
                    printf(
            "  Edge-triggered events are supported.");
                
            if ((f & EV_FEATURE_O1))
                    printf(
            "  O(1) event notification is supported.");
                
            if ((f & EV_FEATURE_FDS))
                    printf(
            "  All FD types are supported.");
                puts(
            "");
            }

            這個函數(shù)定義在<event2/event.h>中。event_base_get_method()首次出現(xiàn)在1.4.3版本中,其他函數(shù)首次出現(xiàn)在2.0.1-alpha版本中。

            4 釋放event_base

            使用完event_base之后,使用event_base_free()進行釋放。

            接口

            void event_base_free(struct event_base *base);

            注意:這個函數(shù)不會釋放當前與event_base關(guān)聯(lián)的任何事件,或者關(guān)閉他們的套接字,或者釋放任何指針。

            event_base_free()定義在<event2/event.h>中,首次由libevent 1.2實現(xiàn)。

            5 設(shè)置event_base的優(yōu)先級

            libevent支持為事件設(shè)置多個優(yōu)先級。然而,event_base默認只支持單個優(yōu)先級。可以調(diào)用event_base_priority_init()設(shè)置event_base的優(yōu)先級數(shù)目。

            接口

            int event_base_priority_init(struct event_base *baseint n_priorities);

            成功時這個函數(shù)返回0,失敗時返回-1。base是要修改的event_base,n_priorities是要支持的優(yōu)先級數(shù)目,這個數(shù)目至少是1。每個新的事件可用的優(yōu)先級將從0(最高)到n_priorities-1(最低)。

            常量EVENT_MAX_PRIORITIES表示n_priorities的上限。調(diào)用這個函數(shù)時為n_priorities給出更大的值是錯誤的。

            注意

            必須在任何事件激活之前調(diào)用這個函數(shù),最好在創(chuàng)建event_base后立刻調(diào)用。

            示例

            關(guān)于示例,請看event_priority_set的文檔。

            默認情況下,與event_base相關(guān)聯(lián)的事件將被初始化為具有優(yōu)先級n_priorities / 2。event_base_priority_init()函數(shù)定義在<event2/event.h>中,從libevent 1.0版就可用了。

            6 在fork()之后重新初始化event_base

            不是所有事件后端都在調(diào)用fork()之后可以正確工作。所以,如果在使用fork()或者其他相關(guān)系統(tǒng)調(diào)用啟動新進程之后,希望在新進程中繼續(xù)使用event_base,就需要進行重新初始化。

            接口

            int event_reinit(struct event_base *base);

            成功時這個函數(shù)返回0,失敗時返回-1。

            示例

            struct event_base *base = event_base_new();

            /*  add some events to the event_base  */

            if (fork()) {
                
            /* In parent */
                continue_running_parent(
            base); /**/
            else {
                
            /* In child */
                event_reinit(
            base);
                continue_running_child(
            base); /**/
            }

            event_reinit()定義在<event2/event.h>中,在libevent 1.4.3-alpha版中首次可用。

            7 廢棄的event_base函數(shù)

            老版本的libevent嚴重依賴“當前”event_base的概念。“當前”event_base是一個由所有線程共享的全局設(shè)置。如果忘記指定要使用哪個event_base,則得到的是當前的。因為event_base不是線程安全的,這很容易導(dǎo)致錯誤。

            老版本的libevent沒有event_base_new(),而有:

            接口

            struct event_base *event_init(void);

            這個函數(shù)的工作與event_base_new()類似,它將分配的event_base設(shè)置成當前的。沒有其他方法改變當前event_base。

            本文描述的函數(shù)有一些用于操作當前event_base的變體,這些函數(shù)與新版本函數(shù)的行為類似,只是它們沒有event_base參數(shù)。

            97久久精品午夜一区二区| 久久久精品日本一区二区三区| 亚洲精品白浆高清久久久久久 | 一级做a爱片久久毛片| 久久青草国产手机看片福利盒子| 日韩久久无码免费毛片软件 | 欧美成a人片免费看久久| 亚洲香蕉网久久综合影视| 国内精品久久久久影院免费| 亚州日韩精品专区久久久| 看久久久久久a级毛片| 国产精品伦理久久久久久| 日产精品久久久一区二区| 久久精品国产第一区二区| 国产成年无码久久久久毛片| 久久综合日本熟妇| 久久久久综合网久久| 一本一本久久a久久综合精品蜜桃| 九九久久精品无码专区| 精品久久久久香蕉网| 久久精品国产亚洲AV久| 国产福利电影一区二区三区久久老子无码午夜伦不 | 国产69精品久久久久久人妻精品| 91精品国产色综久久| 精品久久久久久久久午夜福利| 一级做a爰片久久毛片毛片| 精品久久人人做人人爽综合 | 99精品国产99久久久久久97 | 伊人久久成人成综合网222| 久久综合九色综合欧美狠狠| 久久精品无码专区免费东京热| 亚洲Av无码国产情品久久| 久久se精品一区二区影院| 青青草国产精品久久| 久久免费国产精品一区二区| 久久国产精品无码一区二区三区| 伊人久久大香线蕉亚洲五月天| 亚洲精品乱码久久久久久久久久久久| 亚洲人成无码www久久久| 久久久这里有精品| 天堂无码久久综合东京热|