总结说的有的过大,算是对自己学习的一个总结。兴许会不断补充。
模型总结
muduo是基于非堵塞的IO和事件驱动的网络库。
muduo的总体结构时one loop per thread+threadpool,图例如以下:
mainReactor和subReactor都是EventLoop,在mainReactor中接收连接。把建立后的连接分发到subReactor中。
作者開始在muduo/base中封装了和网络无关的一些操作。如日志、时间、队列、相互排斥量、条件变量、线程、线程池等。给后面网络库的设计带来了极大便利。
在muduo/net中封装了和网络相关的操作,muduo是基于Reactor模式的设计的,结构例如以下:
1、EventLoop是整个模式的核心,它来管理全部事件。one loop per thread说明一个线程仅仅能有一个EventLoop。
它封装了eventfd和timerfd,用来唤醒等待在poll上的线程;eventfd是其它线程唤醒当前线程使用,把任务加入到EventLoop的任务队列后,假设不是EventLoop的owner线程,则要唤醒它来运行任务。timerfd用来实现定时。
2、Poller是个虚基类,真正调用的时PollPoller或EPollPoller。
用来实现IO的复用。事件都注冊到Poller中。
3、Channel和fd一一相应。尽管它不拥有fd。fd须要响应哪些事件都保存在Channel中。且有相应的回调函数。
4、TcpConnection是保存已经建立的连接。它的生命周期模式,因此採用shared_ptr来管理。它负责数据的发送和接收。负责socket fd的关闭。
5、Acceptor主要负责连接的建立。用在服务端。
当建立连接后。它会把连接的控制权转交给TcpConnection。
6、TcpServer是服务端,有Acceptor,用Map保存了当前已经连接的TcpConnection。
7、Connector是负责发起连接的一方,用在client。发起连接比接收连接要难。非堵塞发起连接更难,要处理各种错误,还要考虑连接失败后怎样处理。当连接成功后它会把控制权交给TcpConnection。
8、TcpClient是client,封装了Connector。
技术总结
muduo网络库尽管是用C++编写。可是却没实用到面向对象,用的是基于对象。最大的特点就是到处可见boost::bind,採用绑定回调函数的手法,实现了事件和特定函数的绑定,更加易于理解和使用。
对象生命周期的管理使用了shared_ptr。多线程中,对象的声明周期难以管理,一个线程难以推断对象是否已经析构。作者shared_ptr来管理对象声明周期。
使用weak_ptr防止对象间相互引用。造成内存永久不释放。对于类内部的一些对象,使用scoped_ptr来管理。
非堵塞网络库应用层为什么须要缓冲区,怎么设计缓冲区。发送过快,缓冲区增长太大怎么办。
仅仅使用非递归的相互排斥量,编码逻辑相对简单。
使用前置声明降低.h文件的包括。
……待续
最新评论