我认为看源码的一个比较好的顺序:从.h里面看成员变量,看看这个类到底持有那些成员变量,再从.cc里面去看成员函数的作用,从构造和析构中去看懂哪些对象的生命周期归该类控制。
但是muduo的EventLoopThread实现为自动销毁的。一般loop函数退出整个程序就退出了,所以muduo库的线程池就是启动时分配,并没有释放。所以线程结束一般来说就是整个程序结束。
EventLoopThread在threadFunc中创建了栈上EventLoop loop,threadFunc在构造时与Thread绑定。
EventLoopThread.h
#ifndef MUDUO_NET_EVENTLOOPTHREAD_H
#define MUDUO_NET_EVENTLOOPTHREAD_H
#include "muduo/base/Condition.h"
#include "muduo/base/Mutex.h"
#include "muduo/base/Thread.h"
namespace muduo
{
namespace net
{
class EventLoop;
class EventLoopThread : noncopyable
{
public:
typedef std::function<void(EventLoop*)> ThreadInitCallback;
EventLoopThread(const ThreadInitCallback& cb = ThreadInitCallback(),
const string& name = string());
~EventLoopThread();
EventLoop* startLoop();
private:
void threadFunc();
EventLoop* loop_ GUARDED_BY(mutex_);
bool exiting_; //这里是干嘛的
Thread thread_; //包含了一个Thread对象,每个Thread被绑定运行ThreadFunc
MutexLock mutex_;
Condition cond_ GUARDED_BY(mutex_);
ThreadInitCallback callback_; //初始化回调
};
} // namespace net
} // namespace muduo
#endif // MUDUO_NET_EVENTLOOPTHREAD_H
EventLoopThread.cc
#include "muduo/net/EventLoopThread.h"
#include "muduo/net/EventLoop.h"
using namespace muduo;
using namespace muduo::net;
EventLoopThread::EventLoopThread(const ThreadInitCallback& cb,
const string& name)
: loop_(NULL),
exiting_(false),
thread_(std::bind(&EventLoopThread::threadFunc, this), name),
mutex_(),
cond_(mutex_),
callback_(cb)
{
}
EventLoopThread::~EventLoopThread()
{
exiting_ = true;
if (loop_ != NULL) // not 100% race-free, eg. threadFunc could be running callback_.
{
// still a tiny chance to call destructed object, if threadFunc exits just now.
// but when EventLoopThread destructs, usually programming is exiting anyway.
loop_->quit();
thread_.join();
}
}
//传出当前线程所属的EventLoop
EventLoop* EventLoopThread::startLoop()
{
assert(!thread_.started());
thread_.start();
EventLoop* loop = NULL;
{
MutexLockGuard lock(mutex_);
while (loop_ == NULL) //避免虚假唤醒
{
cond_.wait();
}
loop = loop_;
}
return loop;
}
//执行回调,这个loop_只是一个中转站,用来中转startLoop传出的loop
void EventLoopThread::threadFunc()
{
EventLoop loop;
if (callback_)
{
callback_(&loop);
}
{
MutexLockGuard lock(mutex_);
loop_ = &loop;
cond_.notify();
}
loop.loop();
//assert(exiting_);
MutexLockGuard lock(mutex_);
loop_ = NULL;
}
总结
这个类的结构还是比较清晰的,EventLoopThread对象会持有这个栈上的EventLoop,一直运行Loop,由于线程池大小固定,所以如果Loop退出意味着整个程序也退出了。