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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Libevent详细说明

發布時間:2023/12/15 综合教程 30 生活家
生活随笔 收集整理的這篇文章主要介紹了 Libevent详细说明 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章來自官方文檔的部分翻譯:http://www.wangafu.net/~nickm/libevent-book/

通過這部分的了解,基本上可以使用libevent的常用功能了。有時間建議直接看官方文檔。

一、簡介

  1、Libevent組成

1)evutil:抽象各個平臺上的網絡實現。

2)eventandevent_base:libevent的核心部分,實現了異步的時間回調機制??捎糜诒O聽何時socket可讀寫,與超時,檢測系統信號。

3)bufferevent:libevent事件核心的一種封裝,以實現更簡便的使用。該模塊允許應用程序訪問緩存起來的讀寫事件,以代替socket準備好時馬上通知的方式。

4)evbuffer:實現bufferevent中的基本緩存功能,提供一些有效與簡便的訪問。

二、SetuptheLibeventlibrary

1、指定日志輸出,可以通過event_set_log_callback指定日志輸出(注意指定的日志輸出函數中不應該調用任何libevent中的函數,否則將出現不確定的問題)。

2、處理致命錯誤,可以通過event_set_log_callback指定當發生不可恢復錯誤時的回調函數,在該函數之后不應在調用libevent中的函數。

3、內存管理,可以通過event_set_mem_functions指定內存分配函數

4、多線程與鎖,當在多線程環境下使用libevent時,需要告知libevent使用哪種鎖版本的函數,目前支持pthread與windows鎖

event_set_mem_functions、evthread_use_pthreads

5、Debug鎖的異常使用,evthread_enable_lock_debugging

6、Debugevent的異常使用,event_enable_debug_mode

7、檢測libevent版本信息

8、釋放所有的全局對象libevent_global_shutdown

三、獲取一個event_base對象

1、在開始libevent之前需要有event_base對象,event_base對象可以持有多個的event對象,并且可以輪詢以獲取那個事件已經就緒。

2、創建默認配置的event_base:event_base_new

3、創建可配置的event_base:event_config_new、event_base_new_with_config、event_config_free

4、檢查event_base后端的方法:event_get_supported_method

5、釋放event_base:event_base_free,注意其持有的event不對釋放

6、設置event_base支持event的優先級:event_base_priority_init

7、調用系統的fork后需要reinitevent_base:event_base_reinit

四、啟動事件循環

  1、運行循環,可以對已經注冊了事件的event_base進行事件等待,并得到通知?! ?/p>

#define EVLOOP_ONCE             0x01
#define EVLOOP_NONBLOCK         0x02
#define EVLOOP_NO_EXIT_ON_EMPTY 0x04
int event_base_loop(struct event_base *base, int flags);

  默認情況下,event_base_loop將循環執行直到其中沒有注冊任何事件為止。當檢測到事件被觸發時,該事件被標記為active,并且在循環的后面調用相應的處理函數。EVLOOP_ONCE用于指定執行一次,loop將等待事件觸發,待這些觸發的事件處理完成后loop退出。EVLOOP_NONBLOCK立即檢查是否有事件觸發,若有則處理,然后返回。EVLOOP_NO_EXIT_ON_EMPTY即使event_base中沒有注冊的事件也不退出,直到調用了event_base_loopbreak函數。

  簡化函數evebt_base_dispatch,循環將執行直到沒有事件被注冊,或者調用了event_base_loopbreak或者event_base_loopexit。

2、重新檢查事件

  有時在事件的回調函數中,希望event_base馬上檢查新的事件而不是繼續處理后面已觸發的事件函數,可以調用event_base_loopcontinue函數。

3、獲取libevent內部時間戳:Event_base_gettimeofday_cached、event_base_update_cache_time

4、到處event_base結構內容:Event_base_dump_events

5、遍歷event_base中的所有事件:event_base_foreach_event

五、處理事件

1、事件生命周期:

初始化的:創建event后并且將其關聯到某個event_base;

未決的:當調用了add函數后,該事件變成未決的(即處于等待狀態)

激活的:關聯的等待觸發時,變成激活狀態,隨后對應的回調函數被調用。

若事件的屬性為persistent,則激活后該事件再次變成未決,否則在回調函數返回時結束。

可以通過delete來刪除未決事件,或者通過add將初始轉換成未決狀態

2、創建事件

#define EV_TIMEOUT      0x01
#define EV_READ         0x02
#define EV_WRITE        0x04
#define EV_SIGNAL       0x08
#define EV_PERSIST      0x10
#define EV_ET           0x20
typedef void (*event_callback_fn)(evutil_socket_t, short, void *);
struct event *event_new(struct event_base *base, evutil_socket_t fd,short what, event_callback_fn cb,void *arg);
void event_free(struct event *event);

事件創建之初為non-pending,只有調用了event_add之后才變成pending。

使用示例:

#include <event2/event.h>j 

void cb_func(evutil_socket_t fd, short what, void *arg)
{
        const char *data = arg;
        printf("Got an event on socket %d:%s%s%s%s [%s]",
            (int) fd,
            (what&EV_TIMEOUT) ? " timeout" : "",
            (what&EV_READ)    ? " read" : "",
            (what&EV_WRITE)   ? " write" : "",
            (what&EV_SIGNAL)  ? " signal" : "",
            data);
}

void main_loop(evutil_socket_t fd1, evutil_socket_t fd2)
{
    struct event *ev1, *ev2;
    struct timeval five_seconds = {5,0};
    struct event_base *base = event_base_new();
    ev1 = event_new(base, fd1, EV_TIMEOUT|EV_READ|EV_PERSIST, cb_func,(char*)"Reading event");
    ev2 = event_new(base, fd2, EV_WRITE|EV_PERSIST, cb_func, (char*)"Writing event");
    event_add(ev1, &five_seconds);
    event_add(ev2, NULL);
    event_base_dispatch(base);
}

事件類型:

EV_TIMEOUT:指定超時事件,在創建事件的時候timeout事件被忽略,超時事件在event_add函數中指定。

EV_READ:指定可讀事件

EV_WRITE:指定可寫事件

EV_SIGNAL:指定信號事件

EV_PERSISTENT:指定事件為永久的(即觸發后會再次進入等待)

EV_ET:指定讀寫事件

3、創建自己為回調函數參數的事件:event_self_cbarg

ev = event_new(base, -1, EV_PERSIST, cb_func, event_self_cbarg());

該函數對如下函數event_new(),evtimer_new(),evsignal_new(),event_assign(),evtimer_assign(),andevsignal_assign().同樣有效。

4、超時事件

為了方便使用,libevent提供了以evtime_開頭的宏定義如下:

#define evtimer_new(base, callback, arg) 
    event_new((base), -1, 0, (callback), (arg))
#define evtimer_add(ev, tv) 
    event_add((ev),(tv))
#define evtimer_del(ev) 
    event_del(ev)
#define evtimer_pending(ev, tv_out) 
    event_pending((ev), EV_TIMEOUT, (tv_out))

5、信號事件

Libevent執行POSIX_style的信號。

#define evsignal_new(base, signum, callback, arg) 
    event_new(base, signum, EV_SIGNAL|EV_PERSIST, cb, arg)
struct event *hup_event;
struct event_base *base = event_base_new();

/* call sighup_function on a HUP signal */
hup_event = evsignal_new(base, SIGHUP, sighup_function, NULL);
#define evsignal_add(ev, tv) 
    event_add((ev),(tv))
#define evsignal_del(ev) 
    event_del(ev)
#define evsignal_pending(ev, what, tv_out) 
    event_pending((ev), (what), (tv_out))

注意:1)不要使用信號的方式來監聽超時;2)信號事件只會被一個event_base捕捉,即使為多個event_base添加信號事件也只有一個event_base會得到通知。

6、非對分配的event

7、標記事件的pending與non-pending狀態

int event_add(struct event *ev, const struct timeval *tv);

使用event_add將事件從non-pending狀態變成pending狀態。若事件已經處于pending狀態,并且tv非null則更新該事件的tv事件,若tv為null則對原有狀態沒有任何影響(即還是保留之前的超時設置)。另外tv為等待超時毫秒數。

int event_remove_timer(struct event *ev);

使用event_del將事件狀態變成pending,若已經是pending則不操作。

int event_remove_timer(struct event *ev);

使用event_remove_timer來去除事件的超時事件設置。若事件本身是一個超時事件則該函數相當于event_del函數。

8、事件屬性

int event_priority_set(struct event *event, int priority);

用于設置事件的優先級,數值為從0到event_base支持優先級減一之間。

當有高優先級事件觸發時,將得到先處理,然后再次檢查所有事件,當沒有高優先級事件觸發后才能處理低優先級事件。

優先級數值越低,優先級越高。

9、檢查事件狀態

int event_pending(const struct event *ev, short what, struct timeval *tv_out);

返回事件監聽的處于pending或active狀態的flag。若tv_out非空并且社會自了EV_TIMEOUT則返回剩余的超時事件。(不是很清楚)。  

#define event_get_signal(ev) /* ... */
evutil_socket_t event_get_fd(const struct event *ev);
struct event_base *event_get_base(const struct event *ev);
short event_get_events(const struct event *ev);
event_callback_fn event_get_callback(const struct event *ev);
void *event_get_callback_arg(const struct event *ev);
int event_get_priority(const struct event *ev);
void event_get_assignment(const struct event *event,
        struct event_base **base_out,
        evutil_socket_t *fd_out,
        short *events_out,
        event_callback_fn *callback_out,
        void **arg_out);

10、一次性事件

int event_base_once(struct event_base *, evutil_socket_t, short,  void (*)(evutil_socket_t, short, void *), void *, const struct timeval *);

該事件不支持EV_SIGNAL與EV_PERSISTENT屬性,并且使用默認優先級,當該事件觸發一次后,有libevent自動刪除。

該函數創建的事件不能手動刪除與激活。

11、手動激活事件

void event_active(struct event *ev, int what, short ncalls);

總結

以上是生活随笔為你收集整理的Libevent详细说明的全部內容,希望文章能夠幫你解決所遇到的問題。

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