• <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/Ref3_eventloop.html
            轉(zhuǎn)自:http://blog.sina.com.cn/s/blog_56dee71a0100qe76.html

            運(yùn)行循環(huán)

            一旦有了一個(gè)已經(jīng)注冊(cè)了某些事件的event_base(關(guān)于如何創(chuàng)建和注冊(cè)事件請(qǐng)看下一節(jié)),就需要讓libevent等待事件并且通知事件的發(fā)生。

            接口
            #define EVLOOP_ONCE             0x01
            #define EVLOOP_NONBLOCK         0x02
            #define EVLOOP_NO_EXIT_ON_EMPTY 0x04

            int event_base_loop(struct event_base *baseint flags);

            默認(rèn)情況下,event_base_loop()函數(shù)運(yùn)行event_base直到其中沒有已經(jīng)注冊(cè)的事件為止。執(zhí)行循環(huán)的時(shí)候,函數(shù)重復(fù)地檢查是否有任何已經(jīng)注冊(cè)的事件被觸發(fā)(比如說,讀事件的文件描述符已經(jīng)就緒,可以讀取了;或者超時(shí)事件的超時(shí)時(shí)間即將到達(dá))。如果有事件被觸發(fā),函數(shù)標(biāo)記被觸發(fā)的事件為“激活的”,并且執(zhí)行這些事件。

            在flags參數(shù)中設(shè)置一個(gè)或者多個(gè)標(biāo)志就可以改變event_base_loop()的行為。如果設(shè)置了EVLOOP_ONCE,循環(huán)將等待某些事件成為激活的,執(zhí)行激活的事件直到?jīng)]有更多的事件可以執(zhí)行,然會(huì)返回。如果設(shè)置了EVLOOP_NONBLOCK,循環(huán)不會(huì)等待事件被觸發(fā):循環(huán)將僅僅檢測是否有事件已經(jīng)就緒,可以立即觸發(fā),如果有,則執(zhí)行事件的回調(diào)。

            完成工作后,如果正常退出,event_base_loop()返回0;如果因?yàn)楹蠖酥械哪承┪刺幚礤e(cuò)誤而退出,則返回-1。

            為幫助理解,這里給出event_base_loop()的算法概要:

            偽代碼

            while (any events are registered with the loop,
                    or EVLOOP_NO_EXIT_ON_EMPTY was 
            set) {

                
            if (EVLOOP_NONBLOCK was set, or any events are already active)
                    If any registered events have triggered, mark them active.
                
            else
                    Wait until at least one 
            event has triggered, and mark it active.

                
            for (p = 0; p < n_priorities; ++p {
                   
            if (any event with priority of p is active) {
                      Run all active events with priority of p.
                      
            break/* Do not run any events of a less important priority */
                   }
                }

                
            if (EVLOOP_ONCE was set or EVLOOP_NONBLOCK was set)
                   
            break;
            }

            為方便起見,也可以調(diào)用

            接口

            int event_base_dispatch(struct event_base *base);

            event_base_dispatch()等同于沒有設(shè)置標(biāo)志的event_base_loop()。所以,event_base_dispatch()將一直運(yùn)行,直到?jīng)]有已經(jīng)注冊(cè)的事件了,或者調(diào)用了event_base_loopbreak()或者event_base_loopexit()為止。

            這些函數(shù)定義在<event2/event.h>中,從libevent 1.0版就存在了。

            停止循環(huán)

            如果想在移除所有已注冊(cè)的事件之前停止活動(dòng)的事件循環(huán),可以調(diào)用兩個(gè)稍有不同的函數(shù)。

            接口

            int event_base_loopexit(struct event_base *base,
                                    
            const struct timeval *tv);
            int event_base_loopbreak(struct event_base *base);

            event_base_loopexit()讓event_base在給定時(shí)間之后停止循環(huán)。如果tv參數(shù)為NULL,event_base會(huì)立即停止循環(huán),沒有延時(shí)。如果event_base當(dāng)前正在執(zhí)行任何激活事件的回調(diào),則回調(diào)會(huì)繼續(xù)運(yùn)行,直到運(yùn)行完所有激活事件的回調(diào)之才退出。

            event_base_loopbreak()讓event_base立即退出循環(huán)。它與event_base_loopexit(base,NULL)的不同在于,如果event_base當(dāng)前正在執(zhí)行激活事件的回調(diào),它將在執(zhí)行完當(dāng)前正在處理的事件后立即退出。

            注意event_base_loopexit(base,NULL)和event_base_loopbreak(base)在事件循環(huán)沒有運(yùn)行時(shí)的行為不同:前者安排下一次事件循環(huán)在下一輪回調(diào)完成后立即停止(就好像帶EVLOOP_ONCE標(biāo)志調(diào)用一樣);后者卻僅僅停止當(dāng)前正在運(yùn)行的循環(huán),如果事件循環(huán)沒有運(yùn)行,則沒有任何效果。

            這兩個(gè)函數(shù)都在成功時(shí)返回0,失敗時(shí)返回-1。

            示例:立即關(guān)閉

            #include <event2/event.h>

            /* Here's a callback function that calls loopbreak */
            void cb(int sock, short what, void *arg)
            {
                
            struct event_base *base = arg;
                event_base_loopbreak(
            base);
            }

            void main_loop(struct event_base *base, evutil_socket_t watchdog_fd)
            {
                
            struct event *watchdog_event;

                
            /* Construct a new event to trigger whenever there are any bytes to
                   read from a watchdog socket.  When that happens, we'll call the
                   cb function, which will make the loop exit immediately without
                   running any other active events at all.
                 
            */
                watchdog_event 
            = event_new(base, watchdog_fd, EV_READ, cb, base);

                event_add(watchdog_event, NULL);

                event_base_dispatch(
            base);
            }

            示例:執(zhí)行事件循環(huán)10秒,然后退出

            #include <event2/event.h>

            void run_base_with_ticks(struct event_base *base)
            {
              
            struct timeval ten_sec;

              ten_sec.tv_sec 
            = 10;
              ten_sec.tv_usec 
            = 0;

              
            /* Now we run the event_base for a series of 10-second intervals, printing
                 "Tick" after each.  For a much better way to implement a 10-second
                 timer, see the section below about persistent timer events. 
            */
              
            while (1) {
                 
            /* This schedules an exit ten seconds from now. */
                 event_base_loopexit(
            base&ten_sec);

                 event_base_dispatch(
            base);
                 puts(
            "Tick");
              }
            }

            有時(shí)候需要知道對(duì)event_base_dispatch()或者event_base_loop()的調(diào)用是正常退出的,還是因?yàn)檎{(diào)用event_base_loopexit()或者event_base_break()而退出的。可以調(diào)用下述函數(shù)來確定是否調(diào)用了loopexit或者break函數(shù)。

            接口

            int event_base_got_exit(struct event_base *base);
            int event_base_got_break(struct event_base *base);

            這兩個(gè)函數(shù)分別會(huì)在循環(huán)是因?yàn)檎{(diào)用event_base_loopexit()或者event_base_break()而退出的時(shí)候返回true,否則返回false。下次啟動(dòng)事件循環(huán)的時(shí)候,這些值會(huì)被重設(shè)。

            這些函數(shù)聲明在<event2/event.h>中。event_break_loopexit()函數(shù)首次在libevent 1.0c版本中實(shí)現(xiàn);event_break_loopbreak()首次在libevent 1.4.3版本中實(shí)現(xiàn)。

            檢查內(nèi)部時(shí)間緩存

            有時(shí)候需要在事件回調(diào)中獲取當(dāng)前時(shí)間的近似視圖,但不想調(diào)用gettimeofday()(可能是因?yàn)镺S將gettimeofday()作為系統(tǒng)調(diào)用實(shí)現(xiàn),而你試圖避免系統(tǒng)調(diào)用的開銷)。

            在回調(diào)中,可以請(qǐng)求libevent開始本輪回調(diào)時(shí)的當(dāng)前時(shí)間視圖。

            接口

            int event_base_gettimeofday_cached(struct event_base *base,
                
            struct timeval *tv_out);

            如果當(dāng)前正在執(zhí)行回調(diào),event_base_gettimeofday_cached()函數(shù)設(shè)置tv_out參數(shù)的值為緩存的時(shí)間。否則,函數(shù)調(diào)用evutil_gettimeofday()獲取真正的當(dāng)前時(shí)間。成功時(shí)函數(shù)返回0,失敗時(shí)返回負(fù)數(shù)。

            注意,因?yàn)閘ibevent在開始執(zhí)行回調(diào)的時(shí)候緩存時(shí)間值,所以這個(gè)值至少是有一點(diǎn)不精確的。如果回調(diào)執(zhí)行很長時(shí)間,這個(gè)值將非常不精確。

            這個(gè)函數(shù)是libevent 2.0.4-alpha新引入的。

            轉(zhuǎn)儲(chǔ)event_base的狀態(tài)

            接口

            void event_base_dump_events(struct event_base *base, FILE *f);

            為幫助調(diào)試程序(或者調(diào)試libevent),有時(shí)候可能需要加入到event_base的事件及其狀態(tài)的完整列表。調(diào)用event_base_dump_events()可以將這個(gè)列表輸出到指定的文件中。

            這個(gè)列表是人可讀的,未來版本的libevent將會(huì)改變其格式。

            這個(gè)函數(shù)在libevent 2.0.1-alpha版本中引入。

            廢棄的事件循環(huán)函數(shù)

            前面已經(jīng)討論過,老版本的libevent 具有“當(dāng)前”event_base的概念。

            本文討論的某些事件循環(huán)函數(shù)具有操作當(dāng)前event_base的變體。除了沒有base參數(shù)外,這些函數(shù)跟當(dāng)前新版本函數(shù)的行為相同。

            注意

            2.0版本之前的event_base是不支持鎖的,所以這些函數(shù)并不是完全線程安全的:不允許在執(zhí)行事件循環(huán)的線程之外的其他線程中調(diào)用_loopbreak()或者_(dá)loopexit()函數(shù)。

            亚洲欧美日韩久久精品第一区| 亚洲天堂久久精品| 久久久www免费人成精品| 久久久久久精品免费看SSS| 久久久久久午夜成人影院| 久久se这里只有精品| 伊人久久大香线蕉av不卡| 亚洲国产二区三区久久| 欧美日韩精品久久久久| 91精品国产91久久久久久| 精品久久久久久久国产潘金莲| 久久不见久久见免费视频7| 久久高潮一级毛片免费| 久久久久亚洲AV成人片| 97久久久精品综合88久久| 亚洲精品无码久久毛片| 国产A级毛片久久久精品毛片| 国产精品一区二区久久精品| 亚洲AV伊人久久青青草原| 久久综合久久综合久久| 狠狠色丁香婷婷久久综合| 一本一道久久精品综合| 亚洲国产精品无码久久| 久久婷婷是五月综合色狠狠| 99久久综合狠狠综合久久| 久久精品免费观看| 久久久久久久人妻无码中文字幕爆 | 久久久一本精品99久久精品88| 久久国产精品99久久久久久老狼| 久久久久久国产a免费观看黄色大片 | 国产免费久久精品丫丫| 91精品国产9l久久久久| 蜜臀久久99精品久久久久久小说 | 久久笫一福利免费导航| 一本色综合久久| 超级碰碰碰碰97久久久久| 综合久久精品色| 国产aⅴ激情无码久久| 久久久久亚洲AV片无码下载蜜桃| 色欲久久久天天天综合网精品 | 久久九九兔免费精品6|