LibEvent中文帮助文档-第6章【创建Event_base】

来源:互联网 发布:java多线程什么意思 编辑:程序博客网 时间:2024/05/22 17:31
LiEvent中文帮助文档--第6章【创建Event_base】


   返回主目录


Libevent


快速可移植非阻塞式网络编程

 

 

修订历史

版本

日期

作者

备注

V1.0

2016-11-15

周勇

Libevent编程中文帮助文档

 

文档是2009-2012年由Nick-Mathewson基于Attribution-Noncommercial-Share Alike许可协议3.0创建,未来版本将会使用约束性更低的许可来创建.

此外,本文档的源代码示例也是基于BSD"3条款""修改"条款.详情请参考BSD文件全部条款.本文档最新下载地址:

英文:http://libevent.org/

中文:http://blog.csdn.net/zhouyongku/article/details/53431750

请下载并运行"gitclonegit://github.com/nmathewson/libevent- book.git"获取本文档描述的最新版本源码.




<<上一章>>

6.创建Event_base

在你能使用任何感兴趣的LibEvent函数之前,你需要分配一个或多个event_base结构体.每个event_base结构体拥有一些列的event并且可以通过轮询判断哪个event是激活的.

 

如果一个event_base设置为使用锁定,在多个线程中访问它是安全的,然而只能在一个线程中去处理其事件循环.如果你想在多线程中轮询IO,那么你需要为每个线程分配一个event_base.

 


注意:未来版本将会支持event_base多线程运行

 

每个event_base都有一个方法或后台用来决定哪个event已经准备好了.已经验证的可行方法是:

  • select

  • poll

  • epoll

  • kqueue

  • devpoll

  • evport

  • win32

用户可以通过一些环境变量来禁用某些后台,如果想要kqueue后端,设置变量EVENT_NOKQUEUE,诸如此类.如果你想要从程序内部关闭后台,请查看下面的event_config_avoid_method()方法.

 

6.1创建默认的Event_base

event_base()函数分配和返回了一个默认参数的event_base,它检验环境变量然后分配了一个指向新的event_base的指针,如果错误则返回NULL.

 

择各种方法时,函数会选择其中操作系统支持的最快方法.

 

接口

struct event_base *event_base_new(void); 

就大多数程序而言,这个函数就已经足够了.

event_base_new()函数声明在<event2/event.h>,首次出现在libevent 1.4.3.

 

6.2创建复杂的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_base时设置一个或者多个将在下面介绍的运行时标志.

 

vent_config_require_features()可识别的特征值有:

  • EV_FEATURE_ET:要求支持边沿触发的后端

  • EV_FEATURE_O1: 要求添加、删除单个事件,或者确定哪个事件激活的操作是O(1)复杂度的后端

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

event_config_set_flag()可识别的选项值有:

  • EVENT_BASE_FLAG_NOLOCK:不要为 event_base分配锁.设置这个选项可以为event_base节省一点用于锁定和解锁的时间,但是让在多个线程中访问 event_base成为不安全的.

  • EVENT_BASE_FLAG_IGNORE_ENV:选择使用的后端时,不要检测EVENT_*环境变量.使用这个标志需要三思:这会让用户更难调试你的程序与libevent的交互.

  • EVENT_BASE_FLAG_STARTUP_IOCP:仅用于 Windows, libevent在启动时就启用任何必需的IOCP分发逻辑,而不是按需启用.

  • EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST:告诉 libevent,如果决定使用epoll后端,可以安全地使用更快的基于 changelist的后端.epoll-changelist后端可以在后端的分发函数调用之间,同样的fd多次修改其状态的情况下,避免不必要的系统调用.但是如果传递任何使用 dup ()或者其变体克隆的 fdlibevent, epoll-changelist后端会触发一个内核bug,导致不正确的结果.在不使用epoll后端的情况下,这个标志是没有效果的.也可以通过设置 EVENT_EPOLL_USE_CHANGELIST:环境变量来打开epoll-changelist选项.

    EVENT_BASE_FLAG_NO_CACHE_TIME: 不是在事件循环每次准备执行超时回调时检测当前时间,而是在每次超时回调后进行检测.注意:这会消耗更多的CPU时间.

上述操作event_config的函数都在成功时返回0,失败时返回-1.


____________________________________________________________________________________________________
注意

设置event_config,请求OS不能提供的后端是很容易的.比如说,对于libevent2.0.1-alpha,Windows中是没有O(1)后端的;Linux中也没有同时提供 EV_FEATURE_FDSEV_FEATURE_O1特征的后端.如果创建了 libevent不能满足的配置,event_base_new_with_config()会返回NULL.

____________________________________________________________________________________________________


接口

int event_config_set_num_cpus_hint(struct event_config *cfg, int cpus)


虽然这个函数将来可能会在别的平台上起作用,但就目前来讲它只限于使用Windows的完成端口(IOCP)时使用.调用这个函数来通知event_config创建的event_base要在多线程下充分利用好传入的cpu数量.这只是一个暗示,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不为空,则事件循环会去检验函数返回后的时间,如果max_interval时间过去了,那么就会搜寻那些更高优先级的事件.如果max_callbacks参数非负,事件循环也会在max_callbacks个回调函数返回后检查更多事件.这种规则适用于任何事件的优先级高低算法.

 

示例:设置边缘触发

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标志首次出现是在LibEvent2.0.2-alpha版本中,EVENT_BASE_FLAG_PRECISE_TIMER标志首次出现是在LibEvent2.1.2-alpha版本中.event_config_set_num_cpus_hint()函数最新版本在LibEvent2.0.7-rc,event_config_set_max_dispatch_interval()最新在LibEvent2.1.1-alpha版本,其余是在LibEvent2.0.1-alpha中首次出现.

 



<<下一章>>




0 0