那谁的技术博客

感兴趣领域:高性能服务器编程,存储,算法,Linux内核
随笔 - 210, 文章 - 0, 评论 - 1183, 引用 - 0
数据加载中……

让libevent支持多线程

libevent的使用方式是最开始调用event_init初始化一个全局的event_base指针,以后使用其中的API添加新的事件均是对这个指针进行的操作.

试想如下一种典型的场景:主线程使用libevent处理网络IO事件,接收新连接以及接收完客户端的数据之后将该事件交给辅助线程进行处理,辅助线程处理完了,需要往客户端发送回应数据,则再通过libevent提供的API将这个事件添加到可读事件中.但是,由于libevent中这个event_base指针是全局的,如果多线程同时添加可能会造成多线程不安全问题,这个在libevent的代码注释里面作者也做了注解.

在这个地方有人给出了解决的方案:
已经有现成的解决方案:
http://monkeymail.org/archives/libevent-users/2006-October/000257.html

原作者给的地址好像已经失效了。iunknownspserver 中就是使用了他的代码,可以从这里获得
http://code.google.com/p/spserver/source/browse/trunk/spserver/event_msgqueue.h
(对应的C文件可以通过修改上面文件的后缀名所得).

简单的说一说这个event_msgqueue的原理及使用方式:
它的结构体为:
struct event_msgqueue {
   
int push_fd;
   
int pop_fd;
   
int unlock_between_callbacks;

   
struct event queue_ev;

   sp_thread_mutex_t 
lock;
   
void (*callback)(void *void *);
   
void *cbarg;
   
struct circqueue *queue;
};
其中的queue是保存事件的队列,callback是处理事件的回调函数, lock是线程锁.

首先,它创建了一对socketpair(也就是结构体中的push_fd和pop_fd),将其中的一个通过libevent的event_add接口添加到关注的事件中,它的事件类型的是READ|PERSIST, 也就是说可读同时永不删除,而这个事件的回调函数是msgqueue_pop,这个函数的功能是将当前queue中的数据一一取出并且调用callback函数进行回调处理.
其次,外部的多线程需要往libevent添加事件时使用这个文件提供的msgqueue_push函数进行添加,此时, 往socketpair中发送一个字节的数据, 这么做的目的是为了让第一步已经添加的socketpair得到响应,此时, 由第一步,必然会触发之前注册的回调函数msgqueue_pop,将这个队列中的事件取出来进行处理.

这里使用socketpair起到了一个通知的作用,当队列中有数据时,通过向socketpair发送数据以调用msgqueue_pop,将数据取出来进行处理.
可见,这个event_msgqueue起了一个中间层的作用,辅助线程要往libevent添加事件就通过这个队列,当队列中有数据时再触发libevent的事件处理机制进行处理.设计的非常巧妙.

感谢iunknown兄的指点:)


posted on 2009-01-12 14:49 那谁 阅读(23152) 评论(6)  编辑 收藏 引用 所属分类: 网络编程服务器设计libevent

评论

# re: 让libevent支持多线程  回复  更多评论   

呵呵,你看一下libevent中对信号的处理,和这种方式是一模一样的。Again,这也是很多事件处理框架所采用的方式(pipe或socketpair),即把多种事件源最后都统一到一种事件上去了——在Linux下,通常就是epoll处理的文件事件(socket也是文件)。
2009-01-19 14:46 | Joshua Zhu

# re: 让libevent支持多线程  回复  更多评论   

你 能给出 event_msgqueue的一个完整例子吗?我的email:dragzhb@yahoo.com.cn,能发到我的邮箱吗?多谢!
2010-01-21 15:17 | hbzhang

# re: 让libevent支持多线程  回复  更多评论   

1楼说的对啊,这个就是libevent对signal的处理方式。
libevent就是讲io事件、定时器和信号等事件统一到另外一件事去了。
这里用的到的也是这个思想。
2011-04-22 15:52 | zhanglistar

# re: 让libevent支持多线程  回复  更多评论   

我需要完整的代码啊 初学者 光看这些 还真不懂~~
2013-03-13 17:54 | Metre

# re: 让libevent支持多线程  回复  更多评论   

您好http://code.google.com/p/spserver/source/browse/trunk/spserver/event_msgqueue.h 好像失效了能否发我邮箱729720390@qq.com 谢谢!
2015-03-06 11:53 | ruanquanfu

# re: 让libevent支持多线程  回复  更多评论   

刚开始以为有个新的方法可以实现多线程。。。。其实就试类似pipe的方式, memcache就是这样做的,可以参考一下
2015-05-11 23:12 | fly2010love

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理