为什么用线程池
1.创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率。
2.线程并发数量过多,抢占系统资源从而导致阻塞。
3.对线程进行一些简单的管理。
使用线程池
1.定义一个基本函数类,用户可继承此类实现自定义方法即可使用。
class ThreadBaseFunc {};//用户继承该类,自定义函数即可使用。
2.定义一个函数指针,为基本类的函数对象。
typedef int (ThreadBaseFunc::* FUNC)();//定义函数对象
3.定义一个仿函数类实现,重写“()”运算符。
class ThreadWorker {//工作函数类
public:
ThreadWorker() :thiz(NULL), fun(NULL) {}
ThreadWorker(ThreadBaseFunc* th, FUNC fu) :thiz(th), fun(fu) {}//传入子类指针,多态的实现
ThreadWorker(const ThreadWorker& worker) {//复制构造
if (&worker != this) {
thiz = worker.thiz;
fun = worker.fun;
}
}
ThreadWorker& operator = (const ThreadWorker& worker) {
if (&worker != this) {
thiz = worker.thiz;
fun = worker.fun;
}
return *this;
}
int operator() () {//重载函数对象
if (IsValid()) {
return (thiz->*fun)();
}
return -1;
}
bool IsValid() const{//判断工作函数对象是否有效
return (thiz != NULL) && (fun != NULL);
}
private:
ThreadBaseFunc* thiz;//基本对象类
FUNC fun;//实现的函数
};
4.自定义线程类
class TestThread {//线程类
public:
TestThread() {
m_thread = NULL;
m_bStatus = false;
}
~TestThread(){}
bool Start(){//启动线程函数
m_bStatus = true;//把线程状态置为true
m_thread = (HANDLE)_beginthread(&ThreadEntry,0,this);//开启线程
if (!IsValid()) {//检验线程是否启动成功
m_bStatus = false;
}
return m_bStatus;
}
bool Stop(){//停止线程
if (m_bStatus == false) return false;//判断线程当前状态 false直接返回
m_bStatus == false;
DWORD ret = WaitForSingleObject(m_thread, 1000);//等待一秒判断线程是否结束 WAIT_TIMEOUT为正在运行,WAIT_OBJECT_0 为结束
if (ret == WAIT_TIMEOUT) {
TerminateThread(m_thread, -1);//终止线程
}
UpdateWorker();
return true;
}
void UpdateWorker(const ThreadWorker& worker = ThreadWorker()){//给线程分配任务
if ((m_worker.load() != NULL)&&(m_worker.load()!=&worker)) {//判断原子对象的存储的值是否为NULL或者为worker
ThreadWorker* pWorker = m_worker.load();//加载对象
m_worker.store(NULL);
delete pWorker;//释放对象
}
if (m_worker.load() == &worker) return;//如果是本身,则直接返回
if (!worker.IsValid()) {//判断函数对象是否有效
m_worker.store(NULL);
return;
}
m_worker.store(new ThreadWorker(worker));//把新对象存进原子对象,在堆区分配空间
}
bool IsValid(){//判断线程是否有有效
if ((m_thread == NULL) || (m_thread == INVALID_HANDLE_VALUE)) {//为NULL或者为无效句柄
return false;
}
return WaitForSingleObject(m_thread, 0) == WAIT_TIMEOUT;//
}
bool IsIdle(){//判断当前线程是否空闲
if (m_worker.load() == NULL) return true;
return !m_worker.load()->IsValid();
}
protected:
static void ThreadEntry(void* args) {//线程入口函数
TestThread* thiz = (TestThread*)args;
thiz->ThreadMain();
_endthread();
}
void ThreadMain() {//线程执行函数
while (m_bStatus) {//判断线程状态
if (m_worker.load() == NULL) {//判断现在的函数对象是否有,如果没有则继续循环轮询
Sleep(1);
continue;
}
ThreadWorker worker = *m_worker.load();
if (worker.IsValid()) {//判断函数对象是否可用
if (WaitForSingleObject(m_thread, 0) == WAIT_TIMEOUT) {//判断线程是否正在运行
int ret = worker();
if (ret != 0) {//规定函数对象调用本身返回值为0正常执行
//打印出错结果
}
if (ret < 0) {
m_worker.store(NULL);
}
}
}
else {
Sleep(1);
}
}
}
private:
HANDLE m_thread;//线程句柄
bool m_bStatus;//线程状态 true表示线程正在执行 false表示线程已经结束
std::atomic<ThreadWorker*> m_worker;//原子类装载工作函数对象
};
5.定义线程池类
class TestThreadPool {
TestThreadPool(){}
TestThreadPool(size_t size) {//初始化线程池,参数为线程个数
m_threads.resize(size);
for (size_t i = 0; i < size; i++)
{
m_threads[i] = new TestThread();
}
}
~ZSHThreadPool() {
Stop();//暂停线程池里所有线程
for (size_t i = 0; i < m_threads.size(); i++)
{
delete m_threads[i];
m_threads[i] = NULL;
}
m_threads.clear();//清空队列
}
bool Invoke() {//启动线程池
bool ret = true;
for (size_t i = 0; i < m_threads.size(); i++)
{
if (m_threads[i]->Start() == false) {//所有线程是否启动成功
ret = false;
break;
}
}
if (ret == false) {//如果有未启动成功的线程,暂停所有已启动的线程
for (size_t i = 0; i < m_threads.size(); i++)
{
m_threads[i]->Stop();
}
}
return ret;
}
void Stop() {//暂停所有线程
for (size_t i = 0; i < m_threads.size(); i++)
{
m_threads[i]->Stop();
}
}
int DispatchWorker(const ThreadWorker& worker) {//分发任务
int index = -1;
m_lock.lock();//分发任务加锁,避免出现多个线程同时添加进
for (size_t i = 0; i < m_threads.size(); i++)
{
if (m_threads[i]->IsIdle()) {//判断是否有空闲线程
m_threads[i]->UpdateWorker(worker);
index = i;
break;
}
}
m_lock.unlock();//解锁
return index;//返回下标
}
bool CheckThreadValid(size_t index) {//检查线程是否有效
if (index < m_threads.size()) return m_threads[index]->IsValid();
return false;
}
private:
std::mutex m_lock;//对分发任务加锁
std::vector<TestThread*> m_threads;//线程队列
};
6.实现继承基础类。
class TestThread :public ThreadBaseFunc {
public:
/*....自定义函数*/
int TestFunc1(){
}
int TestFunc2(){
}
};
7.使用线程池类。
int main(){
TestThreadPool pool(6);//创建线程池对象
pool.Invoke();//启动线程池
ThreadWorker worker1(this, (FUNC)&TestThread::TestFunc1);//创建工作函数对象,调用的是TestFunc1
pool.DispatchWorker(worker1);//分发任务
ThreadWorker worker2(this, (FUNC)&TestThread::TestFunc2);//创建工作函数对象,调用的是TestFunc2
pool.DispatchWorker(worker2);//分发任务
}