muduo/base库学习笔记(3)-----Thread类

Thread类

在这里插入图片描述

1 构造函数和析构函数

Thread(ThreadFunc, const string& name = string())构造函数的实现,其中name有默认值为空

Thread::Thread(ThreadFunc func, const string& n)
  : started_(false),
    joined_(false),
    pthreadId_(0),
    tid_(0),
    func_(std::move(func)),
    name_(n),
    latch_(1)
{
  setDefaultName();
}

setDefaultName()函数的实现如下

void Thread::setDefaultName()
{
//num为当前已经创建的线程个数
  int num = numCreated_.incrementAndGet();
  //如果说name为空
  if (name_.empty())
  {
    char buf[32];
    //则默认的名字的Thread+第几个线程
    snprintf(buf, sizeof buf, "Thread%d", num);
    name_ = buf;
  }
}

Thread::~Thread()析构函数的实现

Thread::~Thread()
{
//如果线程已经开始工作,并且并没有设置主线程阻塞等待
//则将子线程和主线程分离
  if (started_ && !joined_)
  {
  //pthreadId为当前线程id
    pthread_detach(pthreadId_);
  }
}

2 其他成员函数的实现

Thread::start()函数的实现

void Thread::start()
{
  assert(!started_);
  started_ = true;
  // FIXME: move(func_)
  detail::ThreadData* data = new detail::ThreadData(func_, name_, &tid_, &latch_);
  //如果线程创建成功,条件变量就开始等待,否则还原初始化的值
  if (pthread_create(&pthreadId_, NULL, &detail::startThread, data))
  {
    started_ = false;
    delete data; // or no delete?
  //  LOG_SYSFATAL << "Failed in pthread_create";
  }
  else
  {
    latch_.wait();
    assert(tid_ > 0);
  }
}

其中detail::ThreadData(func_, name_, &tid_, &latch_)

ThreadData(ThreadFunc func,
             const string& name,
             pid_t* tid,
             CountDownLatch* latch)
    : func_(std::move(func)),
      name_(name),
      tid_(tid),
      latch_(latch)
  { }

线程的回调函数startThread的实现

void* startThread(void* obj)
{
  ThreadData* data = static_cast<ThreadData*>(obj);
  data->runInThread();
  delete data;
  return NULL;
}

runInThread()函数的实现

void runInThread()
  {
  //获取当前线程的进程号
    *tid_ = muduo::CurrentThread::tid();
    tid_ = NULL;
    //条件变量-1变为0,线程开始工作
    latch_->countDown();
    latch_ = NULL;

    muduo::CurrentThread::t_threadName = name_.empty() ? "muduoThread" : name_.c_str();
    ::prctl(PR_SET_NAME, muduo::CurrentThread::t_threadName);
    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
    }

Thread::join()函数的实现

int Thread::join()
{
  assert(started_);
  assert(!joined_);
  joined_ = true;
  //阻塞等待线程结束
  return pthread_join(pthreadId_, NULL);
}


这里面给有一个初始化类

void afterFork()
{
  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()
  {
    muduo::CurrentThread::t_threadName = "main";
    CurrentThread::tid();
    //第一个参数是父子线程都调用的函数
    //第二个参数是主线程调用的函数
    //第三个参数是子线程调用的函数
    pthread_atfork(NULL, NULL, &afterFork);
  }
};

ThreadNameInitializer init;

CurrentThread::tid()回调了下面的函数

void CurrentThread::cacheTid()
{
  if (t_cachedTid == 0)
  {
    t_cachedTid = detail::gettid();
    t_tidStringLength = snprintf(t_tidString, sizeof t_tidString, "%5d ", t_cachedTid);
  }
}


其中gettid()函数的实现

pid_t gettid()
{
  return static_cast<pid_t>(::syscall(SYS_gettid));
}


判断是不是主线程,就是判断当前的线程号码是不是等于当前的进程号

bool CurrentThread::isMainThread()
{
  return tid() == ::getpid();
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值