C++实现线程池

这篇文章简单讨论下线程池。

一.什么是线程池

线程池简单来时就是维护了一组线程的池子,这组线程执行一些相似任务。是一种线程的使用方式。

二.为什么要用线程池

有的时候系统需要处理大量相似任务,频繁创建销毁线程会影响系统性能,这个时候就可以维护一组线程专门处理这些任务。

三.如何实现线程池

重点来了,这里展示一种简易的线程池实现方式,主要是为了描述一下线程池的一种运行模式。

直接看代码。

//threadpool.h

#ifndef THREADPOOL_H
#define THREADPOOL_H

#include <vector>
#include <utility>
#include <mutex>
#include <functional>
#include <queue>
#include <condition_variable>
#include <thread>

#define ERR_MES_1 "输入值不合法"

enum Level
{
	Level_0,
	Level_1,
	Level_2
};

using Task = std::function<void()>;
using TaskPair = std::pair<Level, Task>;

class TaskPriorityCompare
{
public:
	bool operator()(TaskPair taskPair1, TaskPair taskPair2)
	{
		return taskPair1.first > taskPair2.first;
	}
};

using ThreadVec = std::vector<std::thread*>;
using TaskQue = std::priority_queue<TaskPair, std::vector<TaskPair>, TaskPriorityCompare>;
using FinishTaskQue = std::queue<Task>;
using UniqueLock = std::unique_lock<std::mutex>;

class ThreadPool
{
public:
	ThreadPool() = default;
	~ThreadPool()noexcept = default;
	bool Start(int ThreadPoolSize = 3);
	void Stop();
	void AddTask(const Task& task, Level level = Level_2);

protected:
	void LoopExecuteThread();
	Task TakeTask();

private:
	bool m_isStart;
	std::mutex m_mutex;
	std::condition_variable m_condVari;
	int m_threadPoolSize;
	ThreadVec m_threadVec;
	TaskQue m_taskQue;
	FinishTaskQue m_finishTaskQue;
	int m_lastErrCode;
	std::string m_lastErrMes;
};

#endif // !THREADPOOL_H
//threadpool.cpp

#include "threadpool.h"

#include <iostream>

bool ThreadPool::Start(int threadPoolSize)
{
	if (threadPoolSize < 1)
	{
		m_lastErrCode = 1;
		m_lastErrMes = ERR_MES_1;
		return false;
	}

	m_isStart = true;
	m_threadPoolSize = threadPoolSize;

	for (int i = 0; i < m_threadPoolSize; i++)
	{
		m_threadVec.push_back(new std::thread(&ThreadPool::LoopExecuteThread, this));
	}

	return true;
}

void ThreadPool::Stop()
{
	m_isStart = false;
	m_condVari.notify_all();
	
	for (auto ite = m_threadVec.begin(); ite != m_threadVec.end(); ite++)
	{
		(*ite)->join();
		delete* ite;
	}
	
	m_threadVec.clear();
}

void ThreadPool::AddTask(const Task& task, Level level)
{
	UniqueLock lock(m_mutex);
	TaskPair taskPair(level, task);
	m_taskQue.push(taskPair);
	m_condVari.notify_one();
}

void ThreadPool::LoopExecuteThread()
{
	UniqueLock lock(m_mutex);
	lock.unlock();
	
	while (m_isStart)
	{
		lock.lock();
		if (m_taskQue.empty())
		{
			m_condVari.wait(lock);
		}

		std::cout << std::this_thread::get_id() << std::endl;
		
		Task task = TakeTask();
		lock.unlock();
		
		if (task)
		{
			task();
			m_finishTaskQue.push(task);
		}
	}
}

Task ThreadPool::TakeTask()
{
	if (!m_taskQue.empty())
	{
		Task task;
		task = m_taskQue.top().second;
		m_taskQue.pop();
		
		return task;
	}

	return nullptr;
}
//main.cpp

#include "threadpool.h"

#include <iostream>

void Fun1()
{
	std::cout << "Fun1 exec" << std::endl;
}

void Fun2()
{
	std::cout << "Fun2 exec" << std::endl;
}

void Fun3()
{
	std::cout << "Fun3 exec" << std::endl;
}

int main(void)
{
	ThreadPool threadPool;
	int i = 3;

	threadPool.Start(i);

	for (int i = 0; i < 10; i++)
	{
		threadPool.AddTask(Fun1, Level_2);
		threadPool.AddTask(Fun2, Level_1);
		threadPool.AddTask(Fun3, Level_0);
	}

	std::this_thread::sleep_for(std::chrono::seconds(3));
	threadPool.Stop();

	return 0;
}

欢迎讨论,欢迎指正,欢迎转载。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值