base4. Thread线程类

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
  }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值