任何一个线程,只要创建并运行了EventLoop,都称之为IO线程
EventLoopThread创建了一个线程在线程函数中创建了一个EvenLoop对象并调用EventLoop::loop
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
class EventLoopThread : boost::noncopyable
{ public: typedef boost::function<void(EventLoop *)> ThreadInitCallback; EventLoopThread(const ThreadInitCallback &cb = ThreadInitCallback()); EventLoop *startLoop()// 启动线程,该线程就成为了IO线程 private: EventLoopThread::~EventLoopThread()
C++ Code
void EventLoopThread::threadFunc() if (callback_) { loop.loop(); |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include <muduo/net/EventLoop.h>
#include <muduo/net/EventLoopThread.h> #include <stdio.h> using namespace muduo; void runInThread() int main() EventLoopThread loopThread; |
20131108 03:29:12.749530Z 2628 TRACE IgnoreSigPipe Ignore SIGPIPE - EventLoop.cc:51
main(): pid = 2628, tid = 2628
20131108 03:29:12.753135Z 2629 TRACE updateChannel fd = 4 events = 3 - EPollPoller.cc:104
20131108 03:29:12.753794Z 2629 TRACE EventLoop EventLoop created 0xB7415F44 in thread 2629 - EventLoop.cc:76
20131108 03:29:12.754266Z 2629 TRACE updateChannel fd = 5 events = 3 - EPollPoller.cc:104
20131108 03:29:12.754707Z 2629 TRACE loop EventLoop 0xB7415F44 start looping - EventLoop.cc:108
20131108 03:29:12.755088Z 2629 TRACE poll 1 events happended - EPollPoller.cc:65
20131108 03:29:12.756033Z 2629 TRACE printActiveChannels
{5: IN } - EventLoop.cc:271
runInThread(): pid = 2628, tid = 2629
20131108 03:29:13.755730Z 2629 TRACE poll 1 events happended - EPollPoller.cc:65
20131108 03:29:13.756388Z 2629 TRACE printActiveChannels
{5: IN } - EventLoop.cc:271
20131108 03:29:15.755858Z 2629 TRACE poll 1 events happended - EPollPoller.cc:65
20131108 03:29:15.757316Z 2629 TRACE printActiveChannels
{4: IN } - EventLoop.cc:271
20131108 03:29:15.757469Z 2629 TRACE readTimerfd TimerQueue::handleRead() 1 at 1383881355.757345 - TimerQueue.cc:62
runInThread(): pid = 2628, tid = 2629
exit main().
20131108 03:29:16.755942Z 2629 TRACE poll 1 events happended - EPollPoller.cc:65
20131108 03:29:16.755988Z 2629 TRACE printActiveChannels
{5: IN } - EventLoop.cc:271
20131108 03:29:16.756003Z 2629 TRACE loop EventLoop 0xB7415F44 stop looping - EventLoop.cc:133
simba@ubuntu:~/Documents/build/debug/bin$
中取
也是一样的流程,需
2s超时,timerfd_ 可读,执行回调函数runInThread()。那为什么exit
栈上对象析构,在析构函数内loop_ ->quit(), 由于不是在IO
(!quit_) 就能退出IO线程。
IO线程池的功能是开启若干个IO线程,并让这些IO线程处于事件循环的状态
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
class EventLoopThreadPool : boost::noncopyable
{ public: typedef boost::function<void(EventLoop *)> ThreadInitCallback; EventLoopThreadPool(EventLoop *baseLoop); // 如果loops_为空,则loop指向baseLoop_ private: EventLoop *baseLoop_; // 与Acceptor所属EventLoop相同 void EventLoopThreadPool::start(const ThreadInitCallback &cb) started_ = true; for (int i = 0; i < numThreads_; ++i) |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void TcpServer::newConnection(int sockfd, const InetAddress &peerAddr)
{ loop_->assertInLoopThread(); // 按照轮叫的方式选择一个EventLoop EventLoop *ioLoop = threadPool_->getNextLoop(); InetAddress localAddr(sockets::getLocalAddr(sockfd)); TcpConnectionPtr conn(new TcpConnection(ioLoop, connections_[connName] = conn; ioLoop->runInLoop(boost::bind(&TcpConnection::connectEstablished, conn)); } |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h> #include <muduo/net/InetAddress.h> #include <boost/bind.hpp> #include <stdio.h> using namespace muduo; class TestServer void start() private: void onMessage(const TcpConnectionPtr &conn, EventLoop *loop_; int main() InetAddress listenAddr(8888); TestServer server(&loop, listenAddr, 4); loop.loop(); |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// 该函数多次调用是无害的
// 该函数可以跨线程调用 void TcpServer::start() { if (!started_) { started_ = true; threadPool_->start(threadInitCallback_); } if (!acceptor_->listenning()) |
main(): pid = 8628
20131108 11:33:15.190620Z 8628 TRACE updateChannel fd = 4 events = 3 - EPollPoller.cc:104
20131108 11:33:15.191246Z 8628 TRACE EventLoop EventLoop created 0xBFB77D50 in thread 8628 - EventLoop.cc:62
20131108 11:33:15.191568Z 8628 TRACE updateChannel fd = 5 events = 3 - EPollPoller.cc:104
20131108 11:33:15.192270Z 8629 TRACE updateChannel fd = 9 events = 3 - EPollPoller.cc:104
20131108 11:33:15.192625Z 8629 TRACE EventLoop EventLoop created 0xB7484F44 in thread 8629 - EventLoop.cc:62
20131108 11:33:15.192927Z 8629 TRACE updateChannel fd = 10 events = 3 - EPollPoller.cc:104
20131108 11:33:15.193356Z 8629 TRACE loop EventLoop 0xB7484F44 start looping - EventLoop.cc:94
20131108 11:33:15.193759Z 8630 TRACE updateChannel fd = 12 events = 3 - EPollPoller.cc:104
20131108 11:33:15.194100Z 8630 TRACE EventLoop EventLoop created 0xB6AFEF44 in thread 8630 - EventLoop.cc:62
20131108 11:33:15.194398Z 8630 TRACE updateChannel fd = 13 events = 3 - EPollPoller.cc:104
20131108 11:33:15.194786Z 8630 TRACE loop EventLoop 0xB6AFEF44 start looping - EventLoop.cc:94
20131108 11:33:15.195135Z 8631 TRACE updateChannel fd = 15 events = 3 - EPollPoller.cc:104
20131108 11:33:15.195534Z 8631 TRACE EventLoop EventLoop created 0xB60FEF44 in thread 8631 - EventLoop.cc:62
20131108 11:33:15.207467Z 8631 TRACE updateChannel fd = 16 events = 3 - EPollPoller.cc:104
20131108 11:33:15.208169Z 8631 TRACE loop EventLoop 0xB60FEF44 start looping - EventLoop.cc:94
20131108 11:33:15.208940Z 8632 TRACE updateChannel fd = 18 events = 3 - EPollPoller.cc:104
20131108 11:33:15.209576Z 8632 TRACE EventLoop EventLoop created 0xB58FDF44 in thread 8632 - EventLoop.cc:62
20131108 11:33:15.210087Z 8632 TRACE updateChannel fd = 19 events = 3 - EPollPoller.cc:104
20131108 11:33:15.210445Z 8628 TRACE updateChannel fd = 6 events = 3 - EPollPoller.cc:104
20131108 11:33:15.210750Z 8628 TRACE loop EventLoop 0xBFB77D50 start looping - EventLoop.cc:94
20131108 11:33:15.211122Z 8632 TRACE loop EventLoop 0xB58FDF44 start looping - EventLoop.cc:94
20131108 11:33:18.958878Z 8628 TRACE poll 1 events happended - EPollPoller.cc:65
20131108 11:33:18.959167Z 8628 TRACE printActiveChannels {6: IN} - EventLoop.cc:257
20131108 11:33:18.959226Z 8628 INFO TcpServer::newConnection [TestServer] - new connection[TestServer:0.0.0.0:8888#1] from 127.0.0.1:56411 - TcpServer.cc:93
20131108 11:33:18.959262Z 8628 DEBUG TcpConnection TcpConnection::ctor[TestServer:0.0.0.0:8888#1] at 0x8C84F98fd=20 - TcpConnection.cc:62
20131108 11:33:18.959277Z 8628 TRACE newConnection [1] usecount=1 - TcpServer.cc:111
20131108 11:33:18.959300Z 8628 TRACE newConnection [2] usecount=2 - TcpServer.cc:113
20131108 11:33:18.959322Z 8628 TRACE newConnection [5] usecount=3 - TcpServer.cc:122
20131108 11:33:18.959343Z 8629 TRACE poll 1 events happended - EPollPoller.cc:65
20131108 11:33:18.959365Z 8629 TRACE printActiveChannels {10: IN } - EventLoop.cc:257
20131108 11:33:18.959378Z 8629 TRACE connectEstablished [3] usecount=3 - TcpConnection.cc:78
20131108 11:33:18.959409Z 8629 TRACE updateChannel fd = 20 events = 3 - EPollPoller.cc:104
onConnection(): new connection [TestServer:0.0.0.0:8888#1] from 127.0.0.1:56411
20131108 11:33:18.959433Z 8629 TRACE connectEstablished [4] usecount=3 - TcpConnection.cc:83
20131108 11:33:23.111546Z 8628 TRACE poll 1 events happended - EPollPoller.cc:65
20131108 11:33:23.111628Z 8628 TRACE printActiveChannels {6: IN } - EventLoop.cc:257
20131108 11:33:23.111662Z 8628 INFO TcpServer::newConnection [TestServer] - new connection[TestServer:0.0.0.0:8888#2] from 127.0.0.1:56412 - TcpServer.cc:93
20131108 11:33:23.111680Z 8628 DEBUG TcpConnection TcpConnection::ctor[TestServer:0.0.0.0:8888#2] at 0x8C85128fd=21 - TcpConnection.cc:62
20131108 11:33:23.111693Z 8628 TRACE newConnection [1] usecount=1 - TcpServer.cc:111
20131108 11:33:23.111722Z 8628 TRACE newConnection [2] usecount=2 - TcpServer.cc:113
20131108 11:33:23.111746Z 8628 TRACE newConnection [5] usecount=3 - TcpServer.cc:122
20131108 11:33:23.111769Z 8630 TRACE poll 1 events happended - EPollPoller.cc:65
20131108 11:33:23.111792Z 8630 TRACE printActiveChannels {13: IN} - EventLoop.cc:257
20131108 11:33:23.111805Z 8630 TRACE connectEstablished [3] usecount=3 - TcpConnection.cc:78
20131108 11:33:23.111813Z 8630 TRACE updateChannel fd = 21 events = 3 - EPollPoller.cc:104
onConnection(): new connection [TestServer:0.0.0.0:8888#2] from 127.0.0.1:56412
20131108 11:33:23.111836Z 8630 TRACE connectEstablished [4] usecount=3 - TcpConnection.cc:83
20131108 11:33:25.219778Z 8631 TRACE poll nothing happended - EPollPoller.cc:74
20131108 11:33:25.219829Z 8632 TRACE poll nothing happended - EPollPoller.cc:74
20131108 11:33:28.969971Z 8629 TRACE poll nothing happended - EPollPoller.cc:74
20131108 11:33:33.119151Z 8630 TRACE poll nothing happended - EPollPoller.cc:74
20131108 11:33:33.119202Z 8628 TRACE poll nothing happended - EPollPoller.cc:74
20131108 11:33:33.754975Z 8629 TRACE poll 1 events happended - EPollPoller.cc:65
20131108 11:33:33.755031Z 8629 TRACE printActiveChannels {20: IN} - EventLoop.cc:257
20131108 11:33:33.755042Z 8629 TRACE handleEvent [6] usecount=2 - Channel.cc:67
onMessage(): received 6 bytes from connection [TestServer:0.0.0.0:8888#1]
20131108 11:33:33.755128Z 8629 TRACE handleEvent [12] usecount=2 - Channel.cc:69
20131108 11:33:35.230224Z 8631 TRACE poll nothing happended - EPollPoller.cc:74
20131108 11:33:35.230274Z 8632 TRACE poll nothing happended - EPollPoller.cc:74
20131108 11:33:36.540663Z 8630 TRACE poll 1 events happended - EPollPoller.cc:65
20131108 11:33:36.540715Z 8630 TRACE printActiveChannels {21: IN} - EventLoop.cc:257
20131108 11:33:36.540727Z 8630 TRACE handleEvent [6] usecount=2 - Channel.cc:67
onMessage(): received 7 bytes from connection [TestServer:0.0.0.0:8888#2]
20131108 11:33:36.540780Z 8630 TRACE handleEvent [12] usecount=2 - Channel.cc:69
20131108 11:33:43.129769Z 8628 TRACE poll nothing happended - EPollPoller.cc:74
20131108 11:33:43.765633Z 8629 TRACE poll nothing happended - EPollPoller.cc:74
= 20 可读)可以参考EventLoop(三)的描述。