本文共 1750 字,大约阅读时间需要 5 分钟。
每个Reactor都属于一个线程;
mainReactor关注的是acceptor,也就是监听socket所关注的事件;
subReactor关注的是已连接socket所关注的事件,每次新到一个连接,就选择一个subReactor来处理该连接(也就选择了该Reactor所对应的线程来处理连接);
若没有一个subReactor,那么mainReactor既要处理监听socket和已连接socket的事件;
eg:35\jmuduo\muduo\net\EventLoopThreadPool.h
35\jmuduo\muduo\net\EventLoopThreadPool.cc 35\jmuduo\muduo\net\CMakeLists.txt 35\jmuduo\muduo\net\TcpServer.cceg测试:35\jmuduo\tests\Reactor_test09.cc
35\jmuduo\tests\CMakeLists.txt测试:
(1)EventLoop loop;中包含一个boost::scoped_ptr poller_;里面会创建一个epoll_creat(),也就是说3号fd被poll fd所占用,称之为pollfd;第3个fd没有关注其某些事件,就不会调用updateChannel,所以也没有打印出来; (2)boost::scoped_ptr timerQueue_;是4号fd,会关注timerQueue_的可读事件,从而调用了updateChannel(),从而调用了epoll的updateChannel(); (3)int wakeupFd_; wakeupFd_应该等于5; (4)接下来是 TcpServer server_;它包含了一个Acceptor,boost::scoped_ptr acceptor_; (5)acceptor_又包含了一个监听socket(Socket acceptSocket_;),是6号fd; (6)第七个fd是int idleFd_;第7个fd没有关注其某些事件,就不会调用updateChannel,所以也没有打印出来; 客户端telnet连接2个过来,服务端的日志如下: 只是运行服务端 当一个telnet连接过来,监听socket产生了可读事件,6这个socket产生了可读事件,打印printActiveChannels,且创建了一个新的socket,fd号=8,需要关注其可读事件 telnet客户端发送数据,此时是socket=8产生了可读事件eg测试:35\jmuduo\tests\Reactor_test10.cc
35\jmuduo\tests\CMakeLists.txt测试:多线程程序的fd的使用情况。telnet启动2个客户端。
6号socket就是监听socket 6号socket就是主线程的EventLoop对象的返回的活跃的Accept通道 接着创建一个新的连接出来,分配一个线程来处理。10是第一个IO线程的EventLoop对象的wakeupFd被唤醒了。 // 由于当前线程与ioLoop所属的线程不在同一个线程,把connectEstablished加入到ioLoop线程所属的EventLoop队列中 ioLoop->runInLoop(boost::bind(&TcpConnection::connectEstablished, conn)); 13号fd被唤醒,与上分析方法类似 客户端发送数据,那么可以看到对应的printActiveChannels的wakeupFd_处理可读事件。下面是2个telnet客户端,发送数据的情况转载地址:http://rmiws.baihongyu.com/