libevent之event_base

Philosophy發表於2024-06-26

目錄
  • 建立event_base
    • 設定預設event_base
    • 設定複雜的event_base
    • 檢查event_base的後端方法
    • 解除分配event_base
    • 在event_base上設定優先順序
    • 在 fork() 之後重新初始化event_base
    • 過時的event_base功能
  • 使用事件迴圈
    • 執行迴圈
    • 停止迴圈
    • 重新檢查事件
    • 檢查內部時間快取
    • 轉儲event_base狀態
    • 對event_base中的每個事件執行函式
    • 過時的事件迴圈函式

建立event_base

在使用任何有趣的 Libevent 函式之前,您需要分配 一種或多種event_base結構。每個event_base結構都包含一組 事件,並可以輪詢以確定哪些事件處於活動狀態。

如果event_base設定為使用鎖,則可以安全地訪問它 多個執行緒。但是,它的迴圈只能在單個執行緒中執行。如果 您希望有多個執行緒輪詢 IO,您需要有一個 每個執行緒event_base。

提示 [Libevent 的未來版本可能支援執行event_bases 跨多個執行緒的事件。

每個event_base都有一個“方法”,或者一個後端,它用來確定哪個 活動已準備就緒。公認的方法有:

  • select
  • poll
  • epoll
  • kqueue
  • devpoll
  • evport
  • win32的

使用者可以使用環境變數禁用特定的後端。如果您想關閉 kqueue 後端,可以設定 EVENT _ NOKQUEUE 環境變數,以此類推。如果希望從程式內部關閉後端,請參閱下面的 event _ config _ void _ method ()說明。

設定預設event_base

event_base_new() 函式分配並返回一個新的事件庫 預設設定。它檢查環境變數並返回 指向新event_base的指標。如果出現錯誤,則返回 NULL。

在方法之間進行選擇時,它會選擇作業系統最快的方法 支援。

介面

struct event_base *event_base_new(void);

對於大多數程式,這就是您所需要的。

event_base_new() 函式在 <event2/event.h> 中宣告。它首先 出現在 Libevent 1.4.3 中。

設定複雜的event_base

如果你想更好地控制你得到什麼樣的event_base,你需要 使用event_config。event_config是一種不透明的結構,可以容納 有關您對event_base偏好的資訊。當你想要一個 event_base,將event_config傳遞給 event_base_new_with_config()。

介面

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);

若要分配具有這些函式的event_base,請呼叫 event_config_new() 以分配新event_config。然後,您在 event_config告訴它您的需求。最後,你可以呼叫 event_base_new_with_config() 獲取新event_base。完成後, 您可以使用 event_config_free() 釋放event_config。

介面

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);

呼叫 event_config_avoid_method 告訴 Libevent 避免特定的 按名稱提供後端。呼叫 event_config_require_feature() 告訴 Libevent 不使用任何不能提供所有功能的後端。 呼叫 event_config_set_flag() 告訴 Libevent 設定一個或多個 構造事件庫時下面的執行時標誌。

event_config_require_features的公認特徵值為:

  • EV_FEATURE_ET

    需要支援邊緣觸發 IO 的後端方法。

  • EV_FEATURE_O1

    需要一種後端方法,其中新增或刪除單個 事件,或讓單個事件變為活動狀態,是一個 O(1) 操作。

  • EV_FEATURE_FDS

    需要可以支援任意檔案的後端方法 描述符型別,而不僅僅是套接字。

event_config_set_flag() 的可識別選項值為:

  • EVENT_BASE_FLAG_NOLOCK

    不要為event_base分配鎖。設定 此選項可以節省一點時間來鎖定和釋放 event_base,但會使訪問它變得不安全且不能用多個執行緒訪問。

  • EVENT_BASE_FLAG_IGNORE_ENV

    不檢查 EVENT_* 環境 選擇要使用的後端方法時的變數。之前要好好想想 使用此標誌:它可以使使用者更難除錯互動 在您的程式和 Libevent 之間。

  • EVENT_BASE_FLAG_STARTUP_IOCP

    僅在 Windows 上,此標誌使 Libevent 在啟動時啟用任何必要的 IOCP 排程邏輯,而不是 按需。

  • EVENT_BASE_FLAG_NO_CACHE_TIME

    而不是每隔檢查一次當前時間 當事件迴圈準備好執行超時回撥時,請在之後檢查 每次超時回撥。這可能會使用比您必須使用的更多的 CPU 有意的,所以要小心!

  • EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST

    告訴 Libevent,如果它決定 使用 epoll 後端,使用更快的基於“changelist”的 “changelist” 是安全的 後端。epoll-changelist 後端可以避免不必要的系統呼叫 同一 FD 在 呼叫後端的排程函式,但它也會觸發核心錯誤 如果您向 Libevent 提供任何 fds 克隆,則會導致錯誤的結果 dup() 或其變體。如果使用後端,則此標誌無效 除了 Epoll。您還可以透過以下方式開啟 epoll-changelist 選項 設定EVENT_EPOLL_USE_CHANGELIST環境變數。

  • EVENT_BASE_FLAG_PRECISE_TIMER

    預設情況下,Libevent 嘗試使用最快的可用計時機制 作業系統提供。如果時間較慢 提供更細粒度計時精度的機制,這 flag 告訴 Libevent 改用該計時機制。如果 作業系統沒有提供這種更慢但更精確的機制, 此標誌無效。

上述操作event_config的函式在成功時都返回 0, -1 失敗時。

注意 設定一個需要後端的event_config很容易,您的 作業系統不提供。例如,從 Libevent 2.0.1-alpha 開始,沒有 O(1) 用於 Windows 的後端,而 Linux 上沒有同時提供這兩種功能的後端 EV_FEATURE_FDS和EV_FEATURE_O1。如果您已進行配置 Libevent 無法滿足,event_base_new_with_config() 將返回 NULL。

介面

int event_config_set_num_cpus_hint(struct event_config *cfg, int cpus)

不過,此函式目前僅在使用 IOCP 時對 Windows 有用 將來它可能會對其他平臺有用。呼叫它告訴 event_config,它產生的event_base應該儘量好好利用 多執行緒時給定數量的 CPU。請注意,這只是一個提示: 事件庫最終使用的 CPU 可能比您選擇的更多或更少。

介面

int event_config_set_max_dispatch_interval(struct event_config *cfg,
    const struct timeval *max_interval, int max_callbacks,
    int min_priority);

此函式透過限制低優先順序的數量來防止優先順序倒置 在檢查更多高優先順序事件之前,可以呼叫事件回撥。 如果 max_interval 為非 null,則事件迴圈會檢查每個事件之後的時間 回撥,如果已透過,則重新掃描高優先順序事件max_interval。 如果max_callbacks為非負數,則事件迴圈還會檢查更多事件 呼叫max_callbacks回撥後。這些規則適用於任何 min_priority 或更高的事件。

示例:首選邊緣觸發的後端

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. */
}

示例:避免優先順序倒置

struct event_config *cfg;
struct event_base *base;

cfg = event_config_new();
if (!cfg)
   /* Handle error */;

/* I'm going to have events running at two priorities.  I expect that
   some of my priority-1 events are going to have pretty slow callbacks,
   so I don't want more than 100 msec to elapse (or 5 callbacks) before
   checking for priority-0 events. */
struct timeval msec_100 = { 0, 100*1000 };
event_config_set_max_dispatch_interval(cfg, &msec_100, 5, 1);

base = event_base_new_with_config(cfg);
if (!base)
   /* Handle error */;

event_base_priority_init(base, 2);

這些函式和型別在 <event2/event.h> 中宣告。

EVENT_BASE_FLAG_IGNORE_ENV標誌首次出現在 Libevent 2.0.2-alpha 中。 EVENT_BASE_FLAG_PRECISE_TIMER標誌首次出現在 Libevent 中 2.1.2-阿爾法。event_config_set_num_cpus_hint() 函式是 Libevent 中的新函式 2.0.7-rc 和 event_config_set_max_dispatch_interval() 是 2.1.1-alpha 中的新功能。 本節中的其他所有內容首先出現在 Libevent 2.0.1-alpha 中。

檢查event_base的後端方法

有時您想檢視哪些功能實際上可用 event_base,或者它使用哪種方法。

介面

const char **event_get_supported_methods(void);

event_get_supported_methods() 函式返回指向 此版本的 Libevent 中支援的方法的名稱。這 陣列中的最後一個元素為 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]);
}
注意 此函式返回編譯 Libevent 的方法列表 來支援。事實上,您的作業系統可能不會 當 Libevent 嘗試執行時,支援它們。例如,您可能在 OSX 版本,其中 kqueue 太有問題而無法使用。

介面

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() 呼叫返回的位掩碼為 它支援的功能。

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("");
}

這些函式在 <event2/event.h> 中定義。event_base_get_method() call 最早在 Libevent 1.4.3 中可用。其他人首次出現在 Libevent 2.0.1-alpha 版本。

解除分配event_base

完成event_base後,可以將其取消分配 event_base_free()。

介面

void event_base_free(struct event_base *base);

請注意,此函式不會解除分配任何事件 當前與event_base關聯,或關閉其任何套接字,或 釋放他們的任何指標。

event_base_free() 函式在 <event2/event.h> 中定義。這是第一個 在 Libevent 1.2 中實現。

在event_base上設定優先順序

Libevent 支援為事件設定多個優先順序。預設情況下, 但是,event_base僅支援單個優先順序。您可以將 透過呼叫 event_base_priority_init() 來event_base上的優先順序數。

介面

int event_base_priority_init(struct event_base *base, int n_priorities);

此函式在成功時返回 0,在失敗時返回 -1。基本引數是 要修改event_base,n_priorities是要修改的優先順序數 支援。它必須至少為 1。新事件的可用優先順序 將從 0(最重要)到 n_priorities-1(最不重要)編號。

有一個常數 EVENT_MAX_PRIORITIES 設定了 n_priorities值。使用更高的 n_priorities的價值。

注意 必須先呼叫此函式,然後才能啟用任何事件。是的 最好在建立event_base後立即呼叫它。

要查詢基地當前支援的優先順序數,您可以 呼叫 event_base_getnpriorities()。

介面

int event_base_get_npriorities(struct event_base *base);

返回值等於 基礎。因此,如果 event_base_get_npriorities() 返回 3,則允許的優先順序 值為 0、1 和 2。

For an example, see the documentation for event_priority_set below.

預設情況下,將初始化與此庫關聯的所有新事件 優先順序等於 n_priorities / 2。

event_base_priority_init函式在 <event2/event.h> 中定義。它有 自 Libevent 1.0 起可用。event_base_get_npriorities() 函式 是 Libevent 2.1.1-alpha 中的新功能。

在 fork() 之後重新初始化event_base

並非所有事件後端在呼叫 fork() 後都能幹淨地保留。因此,如果你的 程式使用 fork() 或相關的系統呼叫來啟動一個新程序, 並且您想在分叉後繼續使用event_base,您可以 需要重新初始化它。

介面

int event_reinit(struct event_base *base);

該函式在成功時返回 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 中可用。

過時的event_base功能

舊版本的 Libevent 在很大程度上依賴於 “當前”event_base。“當前”event_base是一個全球性的環境 在所有執行緒之間共享。如果您忘記指定哪個event_base 你想要的,你得到了現在的。因為event_bases不是 執行緒安全,這可能會變得非常容易出錯。

代替 event_base_new(),有:

介面

struct event_base *event_init(void);

此函式的工作方式類似於 event_base_new(),並設定當前基數 到分配的基地。沒有其他方法可以更改 當前基礎。

本節中的一些event_base函式具有以下變體 在當前基地上操作。這些函式的行為與當前 函式,只是它們沒有基本引數。

當前函式 過時的當前基礎版本
event_base_priority_init() event_priority_init()
event_base_get_method() event_get_method()

最後更新 世界協調時 2024-02-18 20:10:44

使用事件迴圈

這些檔案版權所有 (c) 2009-2012 由 Nick Mathewson 製作 可在知識共享署名-非商業性使用-相同方式共享下使用 許可證,版本 3.0。未來的版本可能會在 限制性許可證。

此外,這些文件中的原始碼示例也已獲得許可 在所謂的“3-Clause”或“Modified”BSD許可證下。請參閱隨這些文件一起分發的 license_bsd 檔案 對於完整的條款。

若要獲取本文件最新版本的原始碼,請安裝 git 並執行“git clone git://github.com/libevent/libevent-book.git”

執行迴圈

一旦您註冊了某些事件的event_base(請參閱下一節 關於如何建立和註冊事件),您將希望 Libevent 等待 事件並提醒您注意它們。

介面

#define EVLOOP_ONCE             0x01
#define EVLOOP_NONBLOCK         0x02
// EVLOOP_NO_EXIT_ON_EMPTY existed since Libevent 2.1
#define EVLOOP_NO_EXIT_ON_EMPTY 0x04

int event_base_loop(struct event_base *base, int flags);

預設情況下,event_base_loop() 函式執行一個event_base,直到那裡 不再有事件註冊。為了執行迴圈,它會反覆檢查 是否觸發了任何已註冊的事件(例如,如果讀取 事件的檔案描述符已準備好讀取,或者如果超時事件的超時為 準備過期)。發生這種情況後,它會將所有觸發的事件標記為 “active”,然後開始執行它們。

您可以透過設定一個或多個標誌來更改 event_base_loop() 的行為 在其 flags 引數中。如果設定了EVLOOP_ONCE,則迴圈將等待 直到某些事件變為活動狀態,然後執行活動事件,直到沒有 更多執行,然後返回。如果設定了EVLOOP_NONBLOCK,則 迴圈不會等待事件觸發:它只會檢查是否 任何事件都準備好立即觸發,如果是,則執行其回撥。

通常,一旦沒有掛起或活動事件,迴圈就會退出。 您可以 透過傳遞 EVLOOP_NO_EXIT_ON_EMPTY 標誌---for 來覆蓋此行為 例如,如果您要從其他執行緒新增事件。如果你 設定EVLOOP_NO_EXIT_ON_EMPTY,迴圈將繼續執行,直到有人 呼叫 event_base_loopbreak() 或呼叫 event_base_loopexit() 或錯誤 發生。

完成後,如果 event_base_loop() 正常退出,則返回 0,如果 它退出是因為後端中的一些未處理的錯誤,如果它退出,則為 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;
}

為方便起見,您還可以呼叫event_base_dispatch方法:

介面

int event_base_dispatch(struct event_base *base);

event_base_dispatch() 呼叫與 event_base_loop() 相同,沒有 設定標誌。因此,它會一直執行,直到沒有更多的註冊事件 或者直到呼叫 event_base_loopbreak() 或 event_base_loopexit()。

這些函式在 <event2/event.h> 中定義。它們從那時起就存在了 Libevent 1.0 版本。

停止迴圈

如果希望活動事件迴圈在所有事件都停止執行之前停止執行 從中刪除,您可以呼叫兩個略有不同的函式。

介面

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在 給定的時間已經過去。如果 tv 引數為 NULL,則event_base停止 無延遲迴圈。如果event_base當前正在執行回撥 對於任何活動 事件,它將繼續執行它們,直到它們全部完成後才退出 跑。

event_base_loopbreak() 函式告訴event_base立刻退出其迴圈。它與 event_base_loopexit(base, NULL) 的不同之處在於,如果 event_base當前正在為任何活動事件執行回撥,它將 退出 在完成它當前正在處理的那個之後。

另請注意,event_base_loopexit(base,NULL) 和 event_base_loopbreak(base) 當沒有事件迴圈執行時,採取不同的行動:LoopExit 計劃下一個 在下一輪迴調後立即停止的事件迴圈的例項 執行(就好像它是用 EVLOOP_ONCE 呼叫的一樣),而 loopbreak 僅 停止當前正在執行的迴圈,如果事件迴圈不停止,則不起作用 執行。

這兩種方法在成功時返回 0,在失敗時返回 -1。

示例:立即關閉

#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);
}

示例:執行事件迴圈 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");
  }
}

有時你可能想判斷你對 event_base_dispatch() 的呼叫是 event_base_loop() 正常退出,或因為呼叫 event_base_loopexit() 或 event_base_break()。您可以使用這些函式來執行以下操作 判斷是否呼叫了 loopexit 或 break:

介面

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

如果迴圈停止,這兩個函式將返回 true 分別為 event_base_loopexit() 或 event_base_break(),並且為 false 否則。下次啟動事件時,將重置其值 圈。

這些函式在 <event2/event.h> 中宣告。event_break_loopexit() 函式最早在 Libevent 1.0c 中實現;event_break_loopbreak() 是 首先在 Libevent 1.4.3 中實現。

重新檢查事件

通常,Libevent 會檢查事件,然後執行所有活動事件 具有最高優先順序,然後再次檢查事件,依此類推。但 有時您可能希望在當前 回撥已執行,並告訴它再次掃描。以此類推 event_base_loopbreak(),您可以使用函式執行此操作 event_base_loopcontinue()。

介面

int event_base_loopcontinue(struct event_base *);

如果我們當前沒有,則呼叫 event_base_loopcontinue() 不起作用 執行事件回撥。

此函式是在 Libevent 2.1.2-alpha 中引入的。

檢查內部時間快取

有時您想大致瞭解內部當前時間 一個事件回撥,並且您希望在不呼叫 getTimeOfDay() 的情況下獲取它 你自己(大概是因為你的作業系統實現了 gettimeofday() 作為 syscall,並且您正在嘗試避免 syscall 開銷)。

在回撥中,您可以向 Libevent 詢問其對當前 它開始執行這一輪迴調的時間:

介面

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

event_base_gettimeofday_cached() 函式將其 tv_out 引數的值設定為快取時間(如果event_base當前為 執行回撥。否則,它會為 evutil_gettimeofday() 呼叫 實際當前時間。成功時返回 0,失敗時返回負數。

請注意,由於 timeval 是在 Libevent 開始執行時快取的 回撥,至少會有點不準確。如果您的回撥 需要很長時間才能執行,它可能非常不準確。強制立即 快取更新,可以呼叫以下函式:

介面

int event_base_update_cache_time(struct event_base *base);

它在成功時返回 0,在失敗時返回 -1,如果基數為 不執行其事件迴圈。

event_base_gettimeofday_cached() 函式是 Libevent 中的新功能 2.0.4-阿爾法。Libevent 2.1.1-alpha 新增了 event_base_update_cache_time()。

轉儲event_base狀態

介面

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

為了幫助除錯你的程式(或除錯 Libevent!),你有時可能會 想要event_base中新增的所有事件及其狀態的完整列表。 呼叫 event_base_dump_events() 將此列表寫入提供的 stdio 檔案。

該列表旨在為人類可讀;它的格式將來改變 Libevent 的版本。

此函式是在 Libevent 2.0.1-alpha 中引入的。

對event_base中的每個事件執行函式

介面

typedef int (*event_base_foreach_event_cb)(const struct event_base *,
    const struct event *, void *);

int event_base_foreach_event(struct event_base *base,
                             event_base_foreach_event_cb fn,
                             void *arg);

您可以使用 event_base_foreach_event() 遍歷每個當前 與 event_base() 關聯的活動或掛起事件。提供的 回撥將在每個事件中呼叫一次,在一個未指定的事件中 次序。將傳遞 event_base_foreach_event() 的第三個引數 作為每次呼叫回撥的第三個引數。

回撥函式必須返回 0 才能繼續迭代,或者其他函式 integer 停止迭代。無論回撥函式最終的值如何 然後,返回將按 event_base_foreach_function() 返回。

回撥函式不得修改其 接收、新增或刪除任何事件到事件庫,或以其他方式 修改與事件庫關聯的任何事件或未定義的行為 可能會發生,甚至包括崩潰和堆砸碎。

event_base鎖將在呼叫期間保持 event_base_foreach_event() — 這將阻止其他執行緒執行此操作 任何對event_base有用的東西,所以請確保你的回撥 不需要很長時間。

此函式是在 Libevent 2.1.2-alpha 中新增的。

過時的事件迴圈函式

如上所述,舊版本的 Libevent API 具有全域性 “當前”event_base的概念。

本節中的一些事件迴圈函式具有以下變體 在當前基地上操作。這些函式的行為與當前 函式,只是它們沒有基本引數。

當前函式 過時的當前基礎版本
event_base_dispatch() event_dispatch()
event_base_loop() event_loop()
event_base_loopexit() event_loopexit()
event_base_loopbreak() event_loopbreak()
注意 因為 event_base 在 Libevent 2.0 之前不支援鎖, 這些函式並不是完全執行緒安全的:這是不允許的 從執行緒呼叫 _loopbreak() 或 _loopexit() 函式 而不是執行事件迴圈的那個。

原文件地址 https://libevent.org/libevent-book/Ref2_eventbase.html

相關文章