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
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值