libevent源码深度剖析十二
libevent源码深度剖析十二
——让libevent支持多线程
张亮
Libevent本身不是多线程安全的,在多核的时代,如何能充分利用CPU的能力呢,这一节来说说如何在多线程环境中使用libevent,跟源代码并没有太大的关系,纯粹是使用上的技巧。
1 错误使用示例
在多核的CPU上只使用一个线程始终是对不起CPU的处理能力啊,那好吧,那就多创建几个线程,比如下面的简单服务器场景。
1 主线程创建工作线程1;
2 接着主线程监听在端口上,等待新的连接;
3 在线程1中执行event事件循环,等待事件到来;
4 新连接到来,主线程调用libevent接口event_add将新连接注册到libevent上;
… …
上面的逻辑看起来没什么错误,在很多服务器设计中都可能用到主线程和工作线程的模式….
可是就在线程1注册事件时,主线程很可能也在操作事件,比如删除,修改,通过libevent的源代码也能看到,没有同步保护机制,问题麻烦了,看起来不能这样做啊,难道只能使用单线程不成!?
2 支持多线程的几种模式
Libevent并不是线程安全的,但这不代表libevent不支持多线程模式,其实方法在前面已经将signal事件处理时就接触到了,那就是消息通知机制。
一句话,“你发消息通知我,然后再由我在合适的时间来处理”;
说到这就再多说几句,再打个比方,把你自己比作一个工作线程,而你的头是主线程,你有一个消息信箱来接收别人发给你的消息,当时头有个新任务要指派给你。
2.1 暴力抢占
那么第一节中使用的多线程方法相当下面的流程:
1 当时你正在做事,比如在写文档;
2 你的头找到了一个任务,要指派给你,比如帮他搞个PPT,哈;
3 头命令你马上搞PPT,你这是不得不停止手头的工作,把PPT搞定了再接着写文档;
…
2.2 纯粹的消息通知机制
那么基于纯粹的消息通知机制的多线程方式就像下面这样:
1 当时你正在写文档;
2 你的头找到了一个任务,要指派给你,帮他搞个PPT;
3 头发个消息到你信箱,有个PPT要帮他搞定,这时你并不鸟他;
4 你写好文档,接着检查消息发现头有个PPT要你搞定,你开始搞PPT;
…
第一种的好处是消息可以立即得到处理,但是很方法很粗暴,你必须立即处理这个消息,所以你必须处理好切换问题,省得把文档上的内容不小心写到PPT里。在操作系统的进程通信中,消息队列(消息信箱)都是操作系统维护的,你不必关心。
第二种的优点是通过消息通知,切换问题省心了,不过消息是不能立即处理的(基于消息通知机制,这个总是难免的),而且所有的内容都通过消息发送,比如PPT的格式、内容等等信息,这无疑增加了通信开销。
2.3 消息通知+同步层
有个折中机制可以减少消息通信的开销,就是提取一个同步层,还拿上面的例子来说,你把工作安排都存放在一个工作队列中,而且你能够保证“任何人把新任务扔
到这个队列”,“自己取出当前第一个任务”等这些操作都能够保证不会把队列搞乱(其实就是个加锁的队列容器)。
再来看看处理过程和上面有什么不同:
1 当时你正在写文档;
2 你的头找到了一个任务,要指派给你,帮他搞个PPT;
2 头有个PPT要你搞定,他把任务push到你的工作队列中,包括了PPT的格式、内容等信息;
3 头发个消息(一个字节)到你信箱,有个PPT要帮他搞定,这时你并不鸟他;
4 你写好文档,发现有新消息(这预示着有新任务来了),检查工作队列知道头有个PPT要你搞定,你开始搞PPT;
…
工作队列其实就是一个加锁的容器(队列、链表等等),这个很容易实现实现;而消息通知仅需要一个字节,具体的任务都push到了在工作队列中,因此想比2.2减少了不少通信开销。
多线程编程有很多陷阱,线程间资源的同步互斥不是一两句能说得清的,而且出现bug很难跟踪调试;这也有很多的经验和教训,因此如果让我选择,在绝大多数情况下都会选择机制3作为实现多线程的方法。
3例子——memcached
Memcached中的网络部分就是基于libevent完成的,其中的多线程模型就是典型的消息通知+同步层机制。下面的图足够说明其多线程模型了,其中有详细的文字说明。

注:该图的具体出处忘记了,感谢原作者。
4 小节
本节更是libevent的使用方面的技巧,讨论了一下如何让libevent支持多线程,以及几种支持多线程的机制,和memcached使用libevent的多线程模型。
libevent源码深度剖析十二的更多相关文章
- libevent源码深度剖析十
libevent源码深度剖析十 ——支持I/O多路复用技术 张亮 Libevent的核心是事件驱动.同步非阻塞,为了达到这一目标,必须采用系统提供的I/O多路复用技术,而这些在Windows.Linu ...
- libevent源码深度剖析二
libevent源码深度剖析二 ——Reactor模式 张亮 前面讲到,整个libevent本身就是一个Reactor,因此本节将专门对Reactor模式进行必要的介绍,并列出libevnet中的几个 ...
- libevent 源码深度剖析十三
libevent 源码深度剖析十三 —— libevent 信号处理注意点 前面讲到了 libevent 实现多线程的方法,然而在多线程的环境中注册信号事件,还是有一些情况需要小心处理,那就是不能在多 ...
- libevent源码深度剖析十一
libevent源码深度剖析十一 ——时间管理 张亮 为了支持定时器,Libevent必须和系统时间打交道,这一部分的内容也比较简单,主要涉及到时间的加减辅助函数.时间缓存.时间校正和定时器堆的时间值 ...
- libevent源码深度剖析九
libevent源码深度剖析九 ——集成定时器事件 张亮 现在再来详细分析libevent中I/O事件和Timer事件的集成,与Signal相比,Timer事件的集成会直观和简单很多.Libevent ...
- libevent源码深度剖析八
libevent源码深度剖析八 ——集成信号处理 张亮 现在我们已经了解了libevent的基本框架:事件管理框架和事件主循环.上节提到了libevent中I/O事件和Signal以及Timer事件的 ...
- libevent源码深度剖析七
libevent源码深度剖析七 ——事件主循环 张亮 现在我们已经初步了解了libevent的Reactor组件——event_base和事件管理框架,接下来就是libevent事件处理的中心部分 — ...
- libevent源码深度剖析六
libevent源码深度剖析六 ——初见事件处理框架 张亮 前面已经对libevent的事件处理框架和event结构体做了描述,现在是时候剖析libevent对事件的详细处理流程了,本节将分析 lib ...
- libevent源码深度剖析五
libevent源码深度剖析五 ——libevent的核心:事件event 张亮 对事件处理流程有了高层的认识后,本节将详细介绍libevent的核心结构event,以及libevent对event的 ...
随机推荐
- TeamTalk源码分析(十) —— 开放一个TeamTalk测试服务器地址和几个测试账号
由于TeamTalk是用于企业内部的即时通讯软件,一般客户端并不提供账号注册功能.如果你仅对TeamTalk的客户端感兴趣,你可以仅仅研究pc端和移动端代码.官方的测试服务器地址已经失效,所以我已经部 ...
- 神经网络中的Softmax激活函数
Softmax回归模型是logistic回归模型在多分类问题上的推广,适用于多分类问题中,且类别之间互斥的场合. Softmax将多个神经元的输出,映射到(0,1)区间内,可以看成是当前输出是属于各个 ...
- 修改Sublime Text3 的侧边栏字体大小
修改Sublime Text3 的侧边栏字体大小 1. 安装”Package Control Package Control”,建议使用官方安装命令:https://sublime.wbond.net ...
- 因实现本地浏览器访问nginx修改配置文件后,安装vsftpd失败
解决方法如下(修改dns配置) vi /etc/resolv.conf 在此文件最后加入:nameserver 8.8.8.8 如果没有vi编辑器可用: echo "nameserver 8 ...
- 前端工程师面试问题归纳(一、问答类html/css/js基础)
一.参考资源 1.前端面试题及答案整理(一) 2.2017年前端面试题整理汇总100题 3.2018最新Web前端经典面试试题及答案 4.[javascript常见面试题]常见前端面试题及答案 5.W ...
- django的多对一,一对一,多对多关系
from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) a ...
- docker 命令记录
从 Docker 镜像仓库获取镜像的命令是 docker pull.其命令格式为: docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] 具体的选项 ...
- Linux 输入子系统 input
一.输入子系统 针对输入设备设计:触摸屏.键盘.按键.传感器.鼠标...... 二.每种设备都属于字符设备驱动,程序的写法步骤也相同 1.实现入口函数 xxx_init() 和卸载函数 xxx_exi ...
- laravel 中间件学习
http://blog.csdn.net/kwinh/article/details/56285204 http://blog.csdn.net/fationyyk/article/details/5 ...
- 【Http认证方式】——Basic认证
访问请求:http://192.168.2.113:8080/geoserver/rest/workspaces时,浏览器弹出窗口需要输入用户名和密码 ,并且,如果不输入或者输入错误,浏览器返回 ...