目录
muduo是陈硕个人使用C++开发的一款网络库,代码写的很有学习价值,总结的内容来自书籍《Linux 多线程服务器端编程》,也是由陈硕编写,可以配合github代码一起使用。
muduo github网址:https://github.com/chenshuo/muduo
一、Reactor
muduo Reactor主要包括以下几个部分:
1、EventLoop
由于每个线程只能有一个EventLoop对象,因此EventLoop的构造函数会检查当前线程是否已经创建了其他EventLoop对象,遇到错误就终止程序,构造函数会记住本对象所属的线程。
2、Channel
每个Channel对象自始至终只属于一个EventLoop,也即每个Channel对象只属于某一个IO线程。每个Channel对象自始至终只负责一个文件描述符的IO事件分发,但并不拥有这个id,也不会在析构的时候关闭这个fd,Channel会把不同的IO事件分发为不同的回调。
Channel::handleEvent()是Channel的核心,由EventLoop::loop()调用,根据revents_值(代表目前活动的事件)分别调用不同的用户回调。
Channel其实是负责IO事件分发,因为Poller只负责IO多路复用,
3、Poller
Poller class是IO多路复用的封装,支持poll()和epoll()两种IO多路复用机制,默认使用epoll,使用环境变量“MUDUO_USE_POLL”来决定是否使用poll,Poller是EventLoop的间接成员,只供其所属的EventLoop在IO线程调用,因此无须加锁,Poller并不拥有Channel,Channel在析构之前必须自己注销。
4、EventLoopThread
EventLoopThread会启动自己的线程,并在其中运行EventLoop::loop()
fillActiveChannels()负责遍历polllfds_,找出有活动事件的fd,把它对应的Channel填入activeChannels,所以EventLoop调用 poll() 就能获得当前活动的事件列表,然后依次调用每个Channel的 handleEvent() 函数。
二、Acceptor
用于accept新TCP连接,并通过回调通知使用者,供TcpServer使用,生命周期由后者控制。Acceptor的数据成员包括Socket、Channel等,其中socket是listening socket,Channel用于观察socket上的readable事件,并回调Acceptor::handleRead(),后者会调用accept()来接受新连接,并回调用户callback。
Acceptor的数据成员和Acceptor::listen()成员函数调用socket()、bind()、listen()等Socket API,Acceptor::listen()的最后一步会让acceptChannel_在socket可读的时候调用Acceptor::handleRead(),handleRead()会调用accept()并回调newConnectionCallback_。