目录
EventLoop相关的Thread三个类:
EventLoop中的Channel、Poller、EpollPoller都实现结束了,接下来是EventLoop相关的Thread三个类。
1. EventLoopThreadPool:
事件循环的线程池,管理事件循环线程调度的。(在TcpServer中)
std::shared_ptr<EventLoopThreadPool> threadPool_;
2. EventLoopThread:
- 在EventLoopThreadPool类中,是EventLoopThreadPool管理的EventLoopThread对象;
- EventLoopThread打包了一个EventLoop和一个Thread;(绑定了一个loop的thread)
3. Thread类:
Thread类就是底层封装的线程,muduo库采用的是Linux原生的pthread_create,代码繁杂,
我们使用C++11的thread类:
Thread成员变量:
Thread成员函数:
构造函数、析构函数:
线程设置成detach,将其变成守护线程,主线程结束,守护线程自动结束。
Thread::setDefaultName()
给线程设置默认的名字
以原子量计数给线程命名:
Thread::start()
Loop启动的时候调用该函数启动线程。
信号量的作用是等待新线程的创建完成,以确保线程对象的 tid_
成员变量被正确设置。
①: 使用 sem_init
初始化了一个信号量 sem
,并将其初始值设置为 0
②:sem_post
递增了信号量的计数值,即释放了一个等待在该信号量上的线程
③:调用 sem_wait
阻塞等待,直到新线程中的 sem_post
被调用,即新线程已经完成了 tid_
的设置。
Thread::join()
主线程等待其他线程完成,确保主线程结束之前所有的子线程都已经完成
Thread.h
#pragma once
#include "noncopyable.h"
#include <functional>
#include <thread>
#include <string>
#include <atomic>
class Thread : noncopyable
{
public:
using ThreadFunc = std::function<void()>;
explicit Thread(ThreadFunc,const std::string &name = std::string());
~Thread(); //析构函数
void strat(); // 启动当前线程
void join(); // 当前线程等待其他线程完了再运行下去
bool started() const {return started_; };
pid_t tid() const {return tid_; }; //返回线程tid
const std::string & name() const {return name_; }; //返回当前线程名字
static int numCreated() { return numCreated_; }; //返回创建的线程数量
private:
void setDefaultName(); //给线程设置默认的名字
bool started_; //启动当前线程
bool joined_; // 当前线程等待其他线完了再运行下去
std::shared_ptr<std::thread> thread_; // 自己掌控线程对象产生的时机,这里直接调用thread thread_它会立即创建一个新线程
pid_t tid_;
ThreadFunc func_; // 存储线程函数
std::string name_; // 调试的时候打印
static std::atomic_int numCreated_; // 对线程数量计数
};
Thread.cc
#include "Thread.h"
#include "CurrentThread.h"
#include <semaphore.h>
std::atomic_int Thread::numCreated_(0);
//Thread构造函数
Thread::Thread(ThreadFunc func,const std::string &name = std::string())
: started_(false)
, joined_(false)
, tid_(0)
, func_(std::move(func))
, name_(name)
{
setDefaultName();//给线程设置默认的名字
}
//Thread析构函数
Thread::~Thread()
{
if(started_ && !joined_) //线程运行起来了且不是
{
// thread 类提供的设置分离线程的方法,成了1个守护线程,主线程计数,守护线程自动结束
thread_->detach();
}
}
//启动当前线程
void Thread::strat()
{
started_ = true;
sem_t sem;
sem_init(&sem, false, 0);
thread_ = std::shared_ptr<std::thread>(new std::thread([&](){
//获取线程的tid
tid_ = CurrentThread::tid();
sem_post(&sem);
//开启一个新线程 专门执行该线程函数
func_(); //包含一个eventLoop
}));//只能指针指向线程对象
//调用start什么时候结束? 必须等待新线程创建完成 返回其tid后才能结束 通过信号量
sem_wait(&sem);
}
//当前线程阻塞,直到被调用的线程执行完毕并退出
//也可以理解为主线程等待其他线程完成,确保主线程结束之前所有的子线程都已经完成
void Thread::join()
{
joined_ = true;
thread_ -> join();
}
//给线程设置默认的名字
void Thread::setDefaultName()
{
int num = ++numCreated_;
if(name_.empty())
{
char buf[32] = {0};
snprintf(buf,sizeof(buf),"Thread&d",num);
name_ = buf;
}
}