挖井

类库大魔王的挖井日记

挖一口属于自己的井


Reactor和Proactor模式

其实我大概10年前就知道ACE了,并且把国内翻译引入的3本以ACE为蓝本的讲C++网络编程的书都收齐了,之所以说是收齐,是因为自己买了两本《C++网络编程》,而由译者马维达送了一本ACE开发指南。但是三本书入手后并没有认真读过,后来工作上也跟C++网络开发基本不相关,于是一直了解不多。直到现在这份工作,虽说终于转向网络开发了,但实际上要么因为老代码已经把底层封装好了,要么就直接用了Boost.Asio而不求甚解。

前两天突然又心血来潮翻出陈硕写的《Linux多线程服务端编程》,看了几页,突然就看懂什么是Reactor和什么是Proactor了。这本书讲的多是作者的经验之谈,风格上跟神作《UNIX网络编程》有所不同,不过总的说来实用性相当高,对实际工作有非常大的指导意义。总的说来Reactor相对容易理解和容易实现一点,稍微实际一点的网络程序大多会采用的select模型,以及Linux/BSD上的性能提升的替代品epoll/kqueue,都是Reactor的实现。在一些第三方库中,如libevent,libev据说也都是Reactor模式。而Windows上的高效网络编程模型完成端口模型是Proactor模式,Boost.Asio也是Proactor模式,怪不得这么多年来我一直没弄明白更用不好。Reactor关注操作就绪通知,收到通知后程序得自己调用相应的系统API来进程IO操作,比如读写socket。而Proactor模式,国内有翻译成前摄器,感觉不是很精确得表示它的含义,只是对这个单词直译了,它关注操作完成通知,收到通知时系统已经帮你完成了IO操作,比如缓冲区里的数据已经被发送出去了或者缓冲区里已经有了接收到的数据。之前我一直疑惑的是Proactor模式下怎么决定要投递一个读操作呢,感觉接收数据这个行为如果不是应用层协议严格定义好的话,完全是个随机发生的事件,用Reactor模式才合适。我看了一点Boost.Asio的示例代码,发现这种情况他们基本上都是这样处理的:一直投递读操作,如果有写的需求了,就临时投递一个写操作,后面仍然继续投递读操作。

《Linux多线程服务端编程》一书非常值得仔细读一下,我就是在这书的引导下,对网络编程有了进一步的了解,我觉得我在公司负责的那个小工程可以仔细重构改进下,目前已经开始动手了,关于这点我后面再写一篇blog来详细讲一下这个设计抉择的演变吧。

本文地址:

https://minidump.info/blog/2014/08/reactor-and-proactor-pattern/

上一篇

薰衣草小熊长虫

妹子生日的时候她表妹送了一个Bridestowe牌的薰衣草小熊给她。当时的多开心的,在电视上看到过某演艺圈的明星就是做这个生意的,在国内受到热捧。前段时间我在淘米的时候偶然发现这才买来没多久的袋装大米里居然有一两只米虫,虽然觉得这种品质的大米里会长米虫很奇怪,但因为小时候自家种自家碾自家吃的米...…

Life 全文阅读
下一篇

重构Relay项目

前面提到过,因为了读了一点《Linux多线程服务端编程》,觉得自己对网络编程有了更多的了解,可以对公司里负责开发维护的那个小项目动手重构了。这个小项目从功能上简单说来,就是个流量转发器,也可说成是个中断器,所以项目名称就叫Relay了。几乎每个刚听到这句话的人,都会第一时间发出疑问:这种功能网...…

Job 全文阅读