Thread类图
数据成员:
bool started_:标识线程是否启动
pthread_t pthreadId_:线程的id
pid_t tid_:线程的真实 pid/tid
ThreadFunc func_:该线程start后要回调的函数,基于对象编程
string name_:线程的名称
static AtomicInt32 numCreated_:已经创建的线程的个数,原子整数类
typedef
typedef boost::function<void ()> ThreadFunc:基于对象编程的回调函数
成员函数:
explicit Thread(const ThreadFunc&, const string& name = string()):构造函数,第二个参数是默认参数,因此只需要传入一个ThreadFunc参数
~Thread():析构函数
void start():启动线程
int join():join归并线程
bool started() const:获取started_,即判断线程是否启动
pid_t tid() const:获取tid_,即获取线程的真实pid/tid
const string& name() const:获取name_,即获取线程的名称
static int numCreated():获取numCreated_的大小,即获取已创建线程的个数
Thread.h
#ifndef MUDUO_BASE_THREAD_H
#define MUDUO_BASE_THREAD_H
#include <muduo/base/Atomic.h>
#include <muduo/base/Types.h>
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
#include <pthread.h>
namespace muduo
{
class Thread : boost::noncopyable
{
public:
typedef boost::function<void ()> ThreadFunc;
//第二个参数是默认参数,因此只需要传入一个ThreadFunc参数
explicit Thread(const ThreadFunc&, const string& name = string());
~Thread();
//启动线程
void start();
//join线程
int join(); // return pthread_join()
//线程是否启动
bool started() const { return started_; }
// pthread_t pthreadId() const { return pthreadId_; }
//获取线程的真实pid/tid
pid_t tid() const { return tid_; }
//获取线程的名称
const string& name() const { return name_; }
//获取已创建线程的个数
static int numCreated() { return numCreated_.get(); }
private:
//线程的入口函数,调用runinthread
static void* startThread(void* thread);
//runInThread()调用回调函数func_
void runInThread();
//线程是否启动
bool started_;
//线程的id
pthread_t pthreadId_;
//线程的真实 pid/tid
pid_t tid_;
//该线程要回调的函数,基于对象编程
ThreadFunc func_;
//线程的名称
string name_;
//已经创建的线程的个数,原子整数类
static AtomicInt32 numCreated_;
};
}
#endif
Thread.cc
#include <muduo/base/Thread.h>
#include <muduo/base/CurrentThread.h>
#include <muduo/base/Exception.h>
//#include <muduo/base/Logging.h>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <linux/unistd.h>
namespace muduo
{
namespace CurrentThread
{
// __thread修饰的变量是线程局部存储的。
__thread int t_cachedTid = 0; // 线程真实pid(tid)的缓存,
// 是为了减少::syscall(SYS_gettid)系统调用的次数
// 提高获取tid的效率
__thread char t_tidString[32]; // 这是tid的字符串表示形式
__thread const char* t_threadName = "unknown";//这是每个线程的名称
//用sametype表示int和pid_t是否相同
const bool sameType = boost::is_same<int, pid_t>::value;
//int和pid_t相同则断言成功
BOOST_STATIC_ASSERT(sameType);
}
namespace detail
{
pid_t gettid()
{ //通过系统调用syscall获取线程tid
return static_cast<pid_t>(::syscall(SYS_gettid));
}
void afterFork()
{ //将主线程init的子线程设置为主线程
muduo::CurrentThread::t_cachedTid = 0;
muduo::CurrentThread::t_threadName = "main";
CurrentThread::tid();
// no need to call pthread_atfork(NULL, NULL, &afterFork);
}
class ThreadNameInitializer
{
public:
ThreadNameInitializer()
{
//将init的名称设置为主线程
muduo::CurrentThread::t_threadName = "main";
//
CurrentThread::tid();
//子进程创建成功后,子进程会调用afterFork
pthread_atfork(NULL, NULL, &afterFork);
}
};
//构造一个全局变量init,在main函数开始之前init就被构造,init为主线程
ThreadNameInitializer init;
}
}
using namespace muduo;
//cacheTid()缓存该线程tid
void CurrentThread::cacheTid()
{
if (t_cachedTid == 0)
{
t_cachedTid = detail::gettid();
int n = snprintf(t_tidString, sizeof t_tidString, "%5d ", t_cachedTid);
assert(n == 6); (void) n;
}
}
//isMainThread()判断该线程是否是主线程
bool CurrentThread::isMainThread()
{
return tid() == ::getpid();
}
AtomicInt32 Thread::numCreated_;
//构造函数,初始化数据成员
Thread::Thread(const ThreadFunc& func, const string& n)
: started_(false),
pthreadId_(0),
tid_(0),
func_(func),
name_(n)
{
numCreated_.increment();
}
Thread::~Thread()
{
// no join
}
//启动线程
void Thread::start()
{
assert(!started_);
started_ = true;
//创建线程,将this指针传递给入口函数startThread
errno = pthread_create(&pthreadId_, NULL, &startThread, this);
if (errno != 0)
{
//LOG_SYSFATAL << "Failed in pthread_create";
}
}
//归并线程
int Thread::join()
{
assert(started_);
return pthread_join(pthreadId_, NULL);
}
//线程的入口函数
void* Thread::startThread(void* obj)
{
//将this指针转换为基类指针
Thread* thread = static_cast<Thread*>(obj);
thread->runInThread();
return NULL;
}
//runInThread()调用回调函数func_
void Thread::runInThread()
{ //缓存线程的tid
tid_ = CurrentThread::tid();
//缓存线程的名称
muduo::CurrentThread::t_threadName = name_.c_str();
try
{
func_();
muduo::CurrentThread::t_threadName = "finished";
}
catch (const Exception& ex)
{
muduo::CurrentThread::t_threadName = "crashed";
fprintf(stderr, "exception caught in Thread %s\n", name_.c_str());
fprintf(stderr, "reason: %s\n", ex.what());
fprintf(stderr, "stack trace: %s\n", ex.stackTrace());
abort();
}
catch (const std::exception& ex)
{
muduo::CurrentThread::t_threadName = "crashed";
fprintf(stderr, "exception caught in Thread %s\n", name_.c_str());
fprintf(stderr, "reason: %s\n", ex.what());
abort();
}
catch (...)
{
muduo::CurrentThread::t_threadName = "crashed";
fprintf(stderr, "unknown exception caught in Thread %s\n", name_.c_str());
throw; // rethrow
}
}