Chinaunix

标题: libevent v2用线程锁效率比pipe通知方式更高么? [打印本页]

作者: happy_fish100    时间: 2012-11-09 10:18
标题: libevent v2用线程锁效率比pipe通知方式更高么?
libvent 1.4.x是非线程安全的,要跨线程执行event_add,会有问题。
因此传统做法是通过pipe来通知宿主线程执行event_add操作。

libevent 2.0.x通过线程锁做到了线程安全,可以跨线程执行event_add。

感觉pipe的开销比线程锁要大一些,我在考虑是否将pipe通知的做法改为libevent 2.0.x内置的线程锁方式。
希望有这方面经验的朋友分享一下经验,谢谢!

作者: osmanthusgfy    时间: 2012-11-09 16:24
在多线程中libvent 1.4.x,使用管道的那种解决方法,之前我研究过,
是非常巧妙,避免了锁,没有显示的线程同步,但是有一个缺点就是:
如果一个线程要注册读或写事件,先要对管道进行读写用来产生一个事件,
这样,中间有延时,特别是并发高的时候. 这种解决方法,必须配合线程池一起使用.

libevent 2.0.x没仔细研究过,不知道你说的线程锁是不是显示用了pthread mutex之类的实现同步操作,
不知道有没有1.4.x的巧妙.

多线程,如果锁越少,效率相对高,但是也得考虑对业务产生影响,比如我前面说的延时。



作者: happy_fish100    时间: 2012-11-09 17:45
回复 2# osmanthusgfy

libevent 2.0.x对event_add等调用会做加锁保护的,使用的是线程互斥锁(thread mutex),以支持跨线程调用。
作者: osmanthusgfy    时间: 2012-11-09 22:03
我扫了一下libevent 2.0.20的源码, 发现event_base已经添加了一个th_base_lock字段用来同步所有操作:
add, dell, event_lopp等. 相对无锁的操作,加锁会影响多线程并发的性能,特别是对单进程多线程模型的服务器.

所以,如果用libvent 1.4.x,配合管道,虽然在连接数多的时候,业务处理可能有延时现象,但由于只需要在event_lopp
的时候加锁,event_add不需要,加锁的次数少,效率要高一些。具体用法可以参考SPServer的实现.


作者: happy_fish100    时间: 2012-11-10 00:02
回复 4# osmanthusgfy
LS说得很有道理。
pipe的write和read操作会进入内核态,存在用户态和内核态切换,我觉得应该比线程锁消耗要大一些。
作者: linux_c_py_php    时间: 2012-11-10 11:23
为啥不是每个线程一个libevent base呢.

memcached/apache的多线程架构思路就OK了,

memcached:监听线程base只负责监听到连接后后dispatch到逻辑线程池(这里pipe+write 1 byte), 管理线程负责线程池增减回收控制, 逻辑线程池每个线程一个base自己掌管自己的I/O. (实际上memcached没有独立的监听线程, 但apache有)

apache: MPM模式, 和memcached的唯一区别就是有独立的监听线程, 并且逻辑线程池是抢夺mutex+cond队列的, 监听线程accept后推向队列, 并且有一个优点就是队列满了, 监听线程可以挂起在cond, 达到了非常简单控制连接数以及维持服务端负载稳定的目的.




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2