EventLoopThread类包装了一个thread类和一个EventLoop类,(one loop per thread)是封装了一个EventLoop的独立线程
意为I/O线程类,EventLoopThread可以创建一个IO线程,通过startLoop返回一个IO线程的loop,threadFunc中开启loop循环,
这个类比较简单,代码都写了注释,不多说
#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();//通过此接口启动io线程,返回subloop
private:
void threadFunc();//线程调用函数,进入loop
EventLoop* loop_ GUARDED_BY(mutex_);//subloop
bool exiting_;//loop退出标志
Thread thread_;
MutexLock mutex_;
Condition cond_ GUARDED_BY(mutex_);
ThreadInitCallback callback_;//线程初始化时调用的函数,不设置则不会调用
};
} // namespace net
} // namespace muduo
#endif // MUDUO_NET_EVENTLOOPTHREAD_H
// Copyright 2010, Shuo Chen. All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
// Author: Shuo Chen (chenshuo at chenshuo dot com)
#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), //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* EventLoopThread::startLoop()
{
assert(!thread_.started());
thread_.start(); //调用pthread_create创建线程,此时有两个线程在运行
//一个是调用EventLoopThread::startLoop()的线程,一个是执行EventLoopThread::threadFunc()的线程(IO线程)
EventLoop* loop = NULL;
{
MutexLockGuard lock(mutex_);
while (loop_ == NULL)
{
cond_.wait(); //须要等待EventLoop对象的创建
}
loop = loop_; //IO线程创建loop_赋给主线程
}
return loop; //主线程返回IO线程创建的EventLoop对象
}
void EventLoopThread::threadFunc() //创建线程时会调用这个函数
{
EventLoop loop; //IO线程也要创建EventLoop对象,还要通知主线程已经创建完毕
if (callback_)//如果设置了cb则diao'y
{
callback_(&loop); //将定义好的loop传入回调
}
{
MutexLockGuard lock(mutex_);
// loop_指针指向了一个栈上的对象,threadFunc函数退出之后。这个指针就失效了
// threadFunc函数退出,就意味着线程退出了,EventLoopThread对象也就没有存在的价值了
// 因而不会有什么大的问题
loop_ = &loop;
cond_.notify(); //创建好,发送通知
}
loop.loop(); // 会在这里循环,直到EventLoopThread析构。此后不再使用loop_訪问EventLoop了
//assert(exiting_);
MutexLockGuard lock(mutex_);
loop_ = NULL;
}