把线程抽出来做一个单独的类
各个类中都可能使用线程,并且线程的操作是类似的,完全可以把线程抽离出去,更好的进行线程控制和改动。
#ifndef _CELL_THREAD_HPP_
#define _CELL_THREAD_HPP_
#include<functional>
#include"CELLSemaphore.hpp"
class CELLThread
{
private:
//定义事件
typedef std::function<void(CELLThread*)> EventCall;
public:
//启动线程
void Start(
EventCall onCreate = nullptr,
EventCall onRun = nullptr,
EventCall onDestory = nullptr)
{
std::lock_guard<std::mutex> lock(_mutex);
if (!_isRun)
{
_isRun = true;
if (onCreate)
_onCreate = onCreate;
if (onRun)
_onRun = onRun;
if (onDestory)
_onDestory = onDestory;
//线程
std::thread t(std::mem_fn(&CELLThread::OnWork), this);
t.detach();
}
}
//关闭线程
void Close()
{
std::lock_guard<std::mutex> lock(_mutex);
if (_isRun)
{
_isRun = false;
_sem.wait();
}
}
//在工作函数中退出
//不需要使用信号量来阻塞等待
//如果使用会阻塞
void Exit()
{
std::lock_guard<std::mutex> lock(_mutex);
if (_isRun)
{
_isRun = false;
}
}
//线程是否启动运行状态
bool isRun()
{
return _isRun;
}
protected:
//线程的运行时的工作函数
void OnWork()
{
if (_onCreate)
_onCreate(this);
if (_onRun)
_onRun(this);
if (_onDestory)
_onDestory(this);
_sem.wakeup();
}
private:
EventCall _onCreate;
EventCall _onRun;
//和close函数的作用并不相同
EventCall _onDestory;
//不同线程中改变数据时需要加锁
std::mutex _mutex;
//控制线程的终止、退出
CELLSemaphore _sem;
//线程是否启动运行中
bool _isRun = false;
};
#endif // !_CELL_THREAD_HPP_
cellthread里面的三个事件是有意义的,这让控制逻辑更加清晰
void Start()
{
_taskServer.Start();
_thread.Start(
//onCreate
nullptr,
//onRun
[this](CELLThread* pThread) {
OnRun(pThread);
},
//onDestory
[this](CELLThread* pThread) {
ClearClients(); //原来是放在OnRun函数里面,现在逻辑更清晰
}
);
}