libevent中文参考手册内容摘要:

性。 接口 除了 evtimer_new()首次出现在 版本中之外,这些宏从 版本就存在了。 构造信号事件 libevent 也可以监测 POSIX 风格的信号。 要构造信号处理器,使用: 接口 除了提供一个信号编号代替文件描述符之外,各个参数与 event_new()相同。 示例 注意 :信号回调是信号发生后在事件循环中被执行的,所以可 以安全地调用通常不能在POSIX 风格信号处理器中使用的函数。 警告:不要在信号事件上设置超时,这可能是不被支持的。 [待修正:真是这样的吗。 ] libevent 也提供了一组方便使用的宏用于处理信号事件: 接口 evsignal_*宏从 版本开始存在。 先前版本中这些宏叫做 signal_add()、signal_del()等等。 关于信号的警告 在当前版本的 libevent 和大多数后端中,每个进程任何时刻只能有一个 event_base可以监听信号。 如果同时向两个 event_base 添加信号 事件,即使是不同的信号,也只有一个 event_base 可以取得信号。 kqueue 后端没有这个限制。 设置不使用堆分配的事件 出于性能考虑或者其他原因,有时需要将事件作为一个大结构体的一部分。 对于每个事件的使用,这可以节省:  内存分配器在堆上分配小对象的开销  对 event 结构体指针取值的时间开销  如果事件不在缓存中,因为可能的额外缓存丢失而导致的时间开销 对于大多数应用来说,这些开销是非常小的。 所以,除非确定在堆上分配事件导致了严重的性能问题,应该坚持使用 event_new()。 如果将来 版本中的 event 结构体更大,不使用 event_new()可能会导致难以诊断的错误。 不在堆上分配 event 具有破坏与其他版本 libevent 二进制兼容性的风险:其他版本中的 event 结构体大小可能不同。 接口 除了 event 参数必须指向一个未初始化的事件之外, event_assign()的参数与event_new()的参数相同。 成功时函数返回 0,如果发生内部错误或者使用错误的参数,函数返回 1。 示例 也可以用 event_assign()初始化栈上分配的,或者静态分配的事件。 警告 不要对已经在 event_base 中未决的事件调用 event_assign(),这可能会导致难以诊断的错误。 如果已经初始化和成为未决的,调用 event_assign()之前需要调用 event_del()。 libevent 提供了方便的宏将 event_assign()用于仅超时事件或者信号事件。 接口 如果需要使用 event_assign(),又要保持与将来版本 libevent 的二进制兼容性,可以请求 libevent 告知 struct event 在运行时应该有多大: 接口 这个函数返回需要为 event 结构体保留的字节数。 再次强调,只有在确信堆分配是一个严重的性能问题时才应该使用这个函数,因为这个函数让代码难以阅读和编写。 注意,将来版本的 event_get_struct_event_size()的返回值可能比 sizeof(struct event)小,这表示 event 结构体末尾的额外字节仅仅是保留用于将来版本 libevent 的填充字节。 下面这个例子跟上面的那个相同,但是不依赖于 中的 event 结构体的大小,而是使用 event_get_struct_size()来获取运行时的正确大小。 示例 event_assign()定义在 event2/中,从 版本开始就存在了。 从 版 本 开 始 , 函 数 返 回 int , 在 这 之 前 函 数 返 回 void。 event_get_struct_event_size()在 版本中引入。 event 结构体定义在event2/中。 2 让事件未决和非未决 构造事件之后,在将其添加到 event_base 之前实际上是不能对其做任何操作的。 使用event_add()将事件添加到 event_base。 接口 在非未决的事件上调用 event_add()将使其在配置的 event_base 中成为未决的。 成功时函数返回 0,失败时返回 1。 如果 tv 为 NULL,添加的事件不会超时。 否则, tv 以秒和微秒指定超时值。 如果对已经未决的事件调用 event_add(),事件将保持未决状态,并在指定的超时时间被重新调度。 注意 :不要设置 tv 为希望超时事件执行的时间。 如果在 2020 年 1 月 1 日设置“ tvtv_sec=time(NULL)+10。 ”,超时事件将会等待 40 年,而不是 10 秒。 接口 对已经初始 化的事件调用 event_del()将使其成为非未决和非激活的。 如果事件不是未决的或者激活的,调用将没有效果。 成功时函数返回 0,失败时返回 1。 注意 :如果在事件激活后,其回调被执行前删除事件,回调将不会执行。 这些函数定义在 event2/中,从 版本就存在了。 3 带优先级的事件 多个事件同时触发时, libevent 没有定义各个回调的执行次序。 可以使用优先级来定义某些事件比其他事件更重要。 在前一章讨论过,每个 event_base 有与之相关的一个或者多个优先级。 在初始化事件之后,但是在 添加到 event_base 之前,可以为其设置优先级。 接口 事件的优先级是一个在 0 和 event_base 的优先级减去 1 之间的数值。 成功时函数返回0,失败时返回 1。 多个不同优先级的事件同时成为激活的时候,低优先级的事件不会运行。 libevent 会执行高优先级的事件,然后重新检查各个事件。 只有在没有高优先级的事件是激活的时候,低优先级的事件才会运行。 示例 如果不为事件设置优先级,则默认的优先级将会是 event_base 的优先级数目除以 2。 这个函数声明在 event2/中,从 版本就存在了。 4 检查事件状态 有时候需要了解事件是否已经添加,检查事件代表什么。 接口 event_pending()函数确定给定的事件是否是未决的或者激活的。 如果是,而且 what参数设置了 EV_READ、 EV_WRITE、 EV_SIGNAL 或者 EV_TIMEOUT 等标志,则函数会返回事件当前为之未决或者激活的所有标志。 如果提供了 tv_out 参数,并且 what 参数中设置了EV_TIMEOUT 标志,而事件当前正因超时事件而未决或者激活,则 tv_out 会返回事件的超时值。 event_get_fd()和 event_get_signal()返回为事件配置的文件描述符或者信号值。 event_get_base()返回为事件配置的 event_base。 event_get_events()返回事件的标志( EV_READ、 EV_WRITE 等)。 event_get_callback()和 event_get_callback_arg()返回事件的回调函数及其参数指针。 event_get_assignment()复制所有为事件分配的字段到提供的指针中。 任何为 NULL的参数会被忽略。 示例 这些函数声明在 event2/中。 event_pending()函数从 版就存在了。 版引入了 event_get_fd()和 event_get_signal()。 引入了event_get_base()。 其他的函数在 版中引入。 5 配置一次触发事件 如果不需要多次添加一个事件,或者要在添加后立即删除事件,而事件又不需要是持久的,则可以使用 event_base_once()。 接口 除了不支持 EV_SIGNAL 或者 EV_PERSIST 之外,这个函数的接 口与 event_new()相同。 安排的事件将以默认的优先级加入到 event_base 并执行。 回调被执行后, libevent 内部将会释放 event 结构。 成功时函数返回 0,失败时返回 1。 不能删除或者手动激活使用 event_base_once()插入的事件:如果希望能够取消事件,应该使用 event_new()或者 event_assign()。 6 手动激活事件 极少数情况下,需要在事件的条件没有触发的时候让事件成为激活的。 接口 这个函数让事件 ev 带有标志 what( EV_READ、 EV_WRITE和 EV_TIMEOUT 的组合)成为激活的。 事件不需要已经处于未决状态,激活事件也不会让它成为未决的。 这个函数定义在 event2/中,从 版本就存在了。 7 优化公用超时 当前版本的 libevent 使用二进制堆算法跟踪未决事件的超时值,这让添加和删除事件超时值具有 O(logN)性能。 对于随机分布的超时值集合,这是优化的,但对于大量具有相同超时值的事件集合,则不是。 比如说,假定有 10000 个事件,每个都需要在添加后 5 秒触发超时事件。 这种情况下,使用双链队列实现才可以取得 O( 1)性能。 自然地, 不希望为所有超时值使用队列,因为队列仅对常量超时值更快。 如果超时值或多或少地随机分布,则向队列添加超时值的性能将是 O( n),这显然比使用二进制堆糟糕得多。 libevent 通过放置一些超时值到队列中,另一些到二进制堆中来解决这个问题。 要使用这个机制,需要向 libevent 请求一个“ 公用超时 (mon timeout)”值,然后使用它来添加事件。 如果有大量具有单个公用超时值的事件,使用这个优化应该可以改进超时处理性能。 接口 这个函数需要 event_base 和要初始化的公用超时值作为参数。 函数返回一个 到特别的timeval结构体的指针,可以使用这个指针指示事件应该被添加到 O( 1)队列,而不是 O( logN)堆。 可以在代码中自由地复制这个特别的 timeval 或者进行赋值,但它仅对用于构造它的特定 event_base 有效。 不能依赖于其实际内容: libevent 使用这个内容来告知自身使用哪个队列。 示例 与所有优化函数一样,除非确信适合使用,应该避免使用公用超时功能。 这个函数由 版本引入。 8 从已清除的内存识别事件 libevent 提供了函数,可以从已经通过设置为 0(比如说,通过 calloc()分配的,或者使用 memset()或者 bzero()清除了的)而清除的内存识别出已初始化的事件。 接口 警告 这个函数不能可靠地从没有初始化的内存块中识别出已经初始化的事件。 除非知道被查询的内存要么是已清除的,要么是已经初始化为事件的,才能使用这个函数。 除非编写一个非常特别的应用,通常不需要使用这个函数。 event_new()返回的事件总是已经初始化的。 示例 event_initialized()函数从 版本就存在了。 9 废弃的事件操作函数 版本之前的 libevent 没有 event_assign()或者 event_new()。 替代的是将事件关联到“当前” event_base 的 event_set()。 如果有多个 event_base,需要记得调用event_base_set()来确定事件确实是关联到当前使用的 event_base 的。 接口 除了使用当前 event_base 之外, event_set()跟 event_assign()是相似的。 event_base_set()用于修改事件所关联到的 event_base。 event_set()具有一些用于更方便地处理定时器和信号的变 体: evtimer_set()大致对应 evtimer_assign(); evsignal_set()大致对应 evsignal_assign()。 版本之前的 libevent 使用“ signal_”作为用于信号的 event_set()等函数变体的前缀,而不是“ evsignal_”(也就是说,有 signal_set()、 signal_add()、 signal_del()、signal_pending()和 signal_initialized())。 远古版本 ( 版之前 )的 libevent 使用“ timeout_”而不是“ evtimer_”。 因此,做代码考古( code archeology)(注:这个翻译似乎不正确,是否有更专业的术语。 比如说,“代码复审”)时可能会看到 timeout_add()、timeout_del()、 timeout_initialized()、 timeout_set()和 timeout_pending()等等。 较老版本( 版之前)的 libevent 用宏 EVENT_FD()和 EVENT_SIGNAL()代表现在的event_get_fd()和 event_get_signal()函数。 这两个宏直接检查 event 结构体的内容,所以会妨碍不同版本之间的二进制兼容性。 在 以及后续版本中,这两个宏仅仅是event_get_fd()和 event_get_signal()的别名。 因为 之前的版本不支持锁,所。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。