目录
muduo网络库模块组成
muduo的组件大致可划分为 5个部分, Reactor、TimerQueue和Eventfd、Acceptor和Connector、TcpConnection、TcpServer和TcpClient。
muduo网络部分的简化类图
如果只注重服务端的话,可以TcpClient省去,Poller在muduo中是个纯虚基类,现在用poll(2)具体化它,省略它们后的结构应该是这样的。
EventLoop和Poller及Channel组成Reactor部分、Acceptor作为TcpServer的监听器、TcpConnection负责处理socket的读写等事件、而TcpServer处理TcpConnection读写完成后的回调事件。
Recator反应器
Reactor由三部分组成,EventLoop、Poller、Channel.
EventLoop即IO线程中的事件循环.它能确保所有注册的事件都在EventLoop对象所在的线程中执行,不用考虑事件的并发。它是线程安全的,且允许其他线程往EventLoop里面塞东西。Poller是IO multiplexing的封装,它是EventLoop的组成,与EventLoop的生命期相当,为EventLoop提供poll()方法。Channel每个Channel对象自始至终只负责一个文件描述符(fd) 的IO事件分发,但它不拥有这个fd,也不会在析构的时候关闭这个fd。每个Channel对象自始至终只属于一个EventLoop,因此每个Channel对象都只属于某一个IO线程。 Channel会把不同的IO事件分发为不同的回调, 例如ReadCallback、 WriteCallback等EventLoop的两个组件
TimerQueue定时器
TimerQueue并未在类图中单独给出,它是EventLoop的组件,为EventLoop提供了定时任务,和周期任务的接口。通过注册一个Timerfd到Poller实现.Connector
在非阻塞网络编程中,发起连接的基本方式是调用connect(2),当socket变得可写时表明连接建立完毕,但是其中要处理各种类型的错误,muduo中把它封装为Connector class.
Connector 和 Acceptor 设计思路基本一致,只是Acceptor通过判断套接字是否可读来执行回调,而Connector是判断套接字是否可写来执行回调,但是要注意的是socket可写不一定就是连接建立好了 , 当连接建立出错时,套接口描述符变成既可读又可写,这时我们可以通过调用getsockopt来得到套接口上待处理的错误(SO_ERROR),如果错误是0表示连接成功。TcpConnection
Buffermuduo中的buffer通过vector和一个栈上空间实现,动态可调,其结构很精妙,感兴趣的话建议直接阅读陈硕Buffer部分设计的文章. 这个buffer主要做为TcpConnection的组件。Socket封装一个套接字,管理了这个套接字描述符的生命期,是TcpConnection的组件,TcpConnection 通过这个套接字描述符注册读写事件,SocketHelp一个纯接口文件,封装了Socket的操作接口。TcpConnection封装一条Tcp连接, 处理这条连接中的读写及错误,连接关闭等事件,这些事件会在TcpConnection的内部先进行处理,然后通过回调函数将TcpConnection缓冲的Buffer提供给用户处理。TcpServer和TcpClient
Tcpserver主要使用组件Acceptor,有新的连接到来时会new一个TcpConnection保存在ConnectionMaps(TcpConnection共享指针的一张映射表)中,通过创建时注册的名字索引管理所有的连接;有数据可读时通过MessgeCallBack回调提供用户使用。TcpClient主要组件Connector, 它的实现与TcpServer相似,只不过每个TcpClient只管理一个TcpConnection。Reactor部分和EventLoop的组件理解后,TcpConnection和TcpServer部分就很好看懂了,所以也没有单独写新的文章。
TcpServer实现部分源码及简单测试 : https://github.com/BethlyRoseDaisley/SimpleMuduo/tree/master/TcpServer
TcpClient实现部分源码及简单测试 : https://github.com/BethlyRoseDaisley/SimpleMuduo/tree/master/TcpClientTcpserver的时序图 :

muduo中的线程安全日志
AsyncLogging异步日志
AsyncLogging一个C++Stream风格的多线程安全非阻塞日志,是muduo库中的另一个部分组成。
这个日志使用了双缓冲机制,这样新建的日志不必等待磁盘操作,也避免了每条新的日志都触发日志线程,而是将多条日志拼程一个大的buffer 和后端buffer交换,后端线程就实时将后端buffer写入本地文件. 相当于批处理,减少线程唤醒频率 ,大大降低开销。
另外 ,为了及时将 日志消息写入文件, 即是 buffer A 中还没有push进来日志 也会每周期执行一次上述的写入操作。
但是有个问题,如果宕机,宕机瞬间缓存中的日志肯定是还没写完的。
用了一阵子,总的来说,这个日志个人很喜欢,轻巧简洁,十分便利。
AsyncLogging日志的格式化部分实现笔记
出处:http://www.cnblogs.com/ailumiyana/
除特别注明外,本站所有文章均为艾露米婭娜原创,欢迎转载分享,但请注明出处。https://www.cnblogs.com/ailumiyana/p/10087539.html
