libevent 学习比较

注意  event_base_dispatch  和event_dispatch  的区别。
个人理解event_base_dispatch 是针对某类base 的。




http://hi.baidu.com/%D0%A1%C6%BD339/blog/item/e913fd8160b006ddbd3e1e08.html

libevent 学习笔记
2008-04-20 19:27

 

libevent的功能还是挺强大的,只学了点event的用法。

介绍个blog,里面有具体实例。

http://blog.gslin.info/2005/11/network-programming-using-libevent-i.html

个人学习的一点体会,可能有不恰当的地方哈。希望多多讨论。

已经成功实现了多线程的libevent使用,见开源代码http://code.google.com/p/qgserver/

struct event_base* event_init(void): 使用前必做的一件事,初始化事件API。

void event_set(struct event *ev, int fd, short event, void (*fn)(int, short, void *),void *arg);
初始化一个事件 ev.
fd 表示文件描述符。
event 关注的事件类型.可用‘|’类型组合。
EV_TIMEOUT-时间通知
EV_SIGNAL-信号通知
EV_READ-可读通知
EV_WRITE-可写通知
EV_PERSIST-额外的标记,表示添加为永久事件,直到调用event_del
fn 函数指针,当事件到达时调用此函数。函数形式必须为void fn(int fd,short event,void *arg)
   其中,fd为当前处理的文件描述符号,event 事件类型,arg 参数指针。
   注:所有参数都将由事件系统自动传入。
arg 为参数指针,和fn中arg对应。

int event_add(struct event *ev, struct timeval *tv);
将事件ev添加入事件系统,等待超时为tv,如果没有时间限制,则设为NULL
成功返回0,否则返回-1且出错原因设置到erron

int event_del(struct event *ev); 从事件系统删除ev,如果事件不存在,或者已被执行,则无效
成功返回0,否则返回-1且出错原因设置到erron

int event_pending(struct event *ev, short event, struct timeval *tv):判断ev的event事件是否正在处理。

int event_initialized(struct event *ev):定义的一个宏,判断ev是否被初始化。

事件优先级:

int event_priority_init(int npriorities):
使用优先级机制首先应做的事,事件优先级初始化,必须在第一个event_dispatch前被调用。

int event_priority_set(struct event *ev, int priority):默认的都是中优先级,调用此函数显示设置ev优先级。

int event_dispatch(void):调用此函数,循环接受事件处理,仅仅出错时才返回。


线程安全相关:
libevent不能同一个event_base被多个线程使用,唯一的方法是每个线程拥有自己的event_base,通过pipe来进行通讯。
并因该如下做:
//初始化event
struct event_base* mEventBase = (struct event_base*)event_init();
//创建一个event(事件)
struct event* mEvAccept = (struct event*)malloc( sizeof( struct event ) );
event_set( mEvAccept, listenFD, EV_READ|EV_PERSIST,
     SP_EventCallback::onAccept, mAcceptArg );
//添加事件到mEventBase
event_base_set( mEventBase, mEvAccept );
event_add( mEvAccept, NULL );

//处理mEventBase 中的事件,在处理的时候,只允许该处理线程对mEventBase 添加和删除event。
//因而设计时可以先创建一个pipe读事件并加入到mEventBase 。如有其他线程想把fd事件加入mEventBase时,只需向pipe写入建好的fd事件指针。
//然后交给pipe EV_READ的触发函数处理。
event_base_dispatch( mEventBase );

下面是作者的回答:
As the guy who added thread support to memcached, I feel qualified to
answer this one:

What libevent doesn't support is sharing a libevent instance across
threads. It works just fine to use libevent in a multithreaded process
where only one thread is making libevent calls.

What also works, and this is what I did in memcached, is to use multiple
instances of libevent. Each call to event_init() will give you back an
"event base," which you can think of as a handle to a libevent instance.
(That's documented in the current manual page, but NOT in the older
manpage on the libevent home page.) You can have multiple threads each
with its own event base and everything works fine, though you probably
don't want to install signal handlers on more than one thread.

In the case of memcached, I allocate one event base per thread at
startup time. One thread handles the TCP listen socket; when a new
request comes in, it calls accept() then hands the file descriptor to
another thread to handle from that point on -- that is, each client is
bound to a particular thread. All you have to do is call
event_base_set() after you call event_set() and before you call event_add().

Unfortunately, you pretty much have to use pipe() to communicate between
libevent threads, That's a limitation, and honestly it's a pretty big
one: it makes a master/worker thread architecture, where one thread
handles all the I/O, much less efficient than you'd like. My initial
implementation in memcached used an architecture like that and it chewed
lots of CPU time. That's not really libevent's fault -- no UNIX-ish
system I'm aware of has an equivalent to the Windows
WaitForMultipleObjects API that allows you to wake up on semaphores /
condition variables and on input from the network. Without that, any
solution is going to end up using pipes (or maybe signals, which have
their own set of issues in a multithreaded context) to wake up the
libevent threads.

-Steve

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于学习libevent,你可以按照以下步骤进行: 1. 了解libeventlibevent是一个开源的事件通知库,它提供了事件驱动的网络编程接口,可以用于开发高性能的网络服务器和客户端应用。它支持多种I/O模型(包括基于事件的和多线程的),并提供了跨平台的兼容性。 2. 安装libevent:你可以从libevent的官方网站(https://libevent.org/)上下载最新版本的libevent,并按照官方文档中的指南进行安装。根据你使用的操作系统不同,安装步骤可能会有所不同。 3. 学习libevent的基本概念:了解libevent中的一些核心概念,如事件循环(event loop)、事件处理器(event handler)、事件回调函数(event callback)等。理解这些概念对于正确使用libevent非常重要。 4. 掌握libevent的使用方法:学习如何使用libevent来编写网络应用程序。这包括创建事件循环、注册事件、定义事件回调函数等。libevent提供了丰富的API,你可以根据自己的需求选择合适的接口进行开发。 5. 深入研究libevent的高级特性:学习libevent的更高级功能,如定时器、信号处理、缓冲区管理等。这些功能可以帮助你更好地控制和优化你的网络应用。 6. 查阅文档和示例代码:libevent的官方网站提供了详细的文档和示例代码,你可以利用这些资源来加深对libevent的理解。此外,还可以参考一些开源项目中使用libevent的实际案例,以便更好地应用于自己的项目中。 记住,学习任何新的库或工具都需要有耐心和实践。不断尝试和练习,结合实际项目,才能更好地掌握和应用libevent。祝你学习顺利!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值