可以用的C++线程池。

不多说,直接上代码。

//ThreadPool.h

#pragma once 
#include <functional> 
#include <future> 
#include <mutex> 
#include <queue> 
#include <thread> 
#include <utility> 
#include <vector> 
#include "SafeQueue.h" 
#include <windows.h>
class ThreadPool {
private:
	class ThreadWorker {//内置线程工作类

	private:
		int m_id; //工作id

		ThreadPool* m_pool;//所属线程池

	public:
		//构造函数

		ThreadWorker(ThreadPool* pool, const int id)
			: m_pool(pool), m_id(id) {
		}
		//重载`()`操作

		void operator()() {
			std::function<void()> func; //定义基础函数类func

			bool dequeued; //是否正在取出队列中元素

			//判断线程池是否关闭,没有关闭,循环提取

			while (!m_pool->m_shutdown) {
				{
					//为线程环境锁加锁,互访问工作线程的休眠和唤醒

					std::unique_lock<std::mutex> lock(m_pool->m_conditional_mutex);
					//如果任务队列为空,阻塞当前线程

					if (m_pool->m_queue.empty()) {
						m_pool->m_conditional_lock.wait(lock); //等待条件变量通知,开启线程

					}
					//取出任务队列中的元素

					dequeued = m_pool->m_queue.dequeue(func);
				}
				//如果成功取出,执行工作函数

				if (dequeued) {
					func();
				}
			}
		}
	};

	bool m_shutdown; //线程池是否关闭

	SafeQueue<std::function<void()>> m_queue;//执行函数安全队列,即任务队列

	std::vector<std::thread> m_threads; //工作线程队列

	std::mutex m_conditional_mutex;//线程休眠锁互斥变量

	std::condition_variable m_conditional_lock; //线程环境锁,让线程可以处于休眠或者唤醒状态

public:
	//线程池构造函数

	ThreadPool(const int n_threads)
		: m_threads(std::vector<std::thread>(n_threads)), m_shutdown(false) {
	}

	ThreadPool(const ThreadPool&) = delete; //拷贝构造函数,并且取消默认父类构造函数

	ThreadPool(ThreadPool&&) = delete; // 拷贝构造函数,允许右值引用

	ThreadPool& operator=(const ThreadPool&) = delete; // 赋值操作

	ThreadPool& operator=(ThreadPool&&) = delete; //赋值操作

	// Inits thread pool

	void init() {
		for (int i = 0; i < m_threads.size(); ++i) {
			m_threads[i] = std::thread(ThreadWorker(this, i));//分配工作线程

		}
	}

	// Waits until threads finish their current task and shutdowns the pool
	void shutdown() {
		while (!m_queue.empty())
		{
			Sleep(1);//等待任务队列处理完成
		}

		m_shutdown = true;
		m_conditional_lock.notify_all(); //通知 唤醒所有工作线程

		for (int i = 0; i < m_threads.size(); ++i) {
			if (m_threads[i].joinable()) { //判断线程是否正在等待

				m_threads[i].join();  //将线程加入等待队列

			}
		}

	}

	// Submit a function to be executed asynchronously by the pool
	//线程的主要工作函数,使用了后置返回类型,自动判断函数返回值
	template<typename F, typename...Args>
	auto submit(F&& f, Args&&... args) -> std::future<decltype(f(args...))> {
		// Create a function with bounded parameters ready to execute
		// 

		std::function<decltype(f(args...))()> func = std::bind(std::forward<F>(f), std::forward<Args>(args)...);//连接函数和参数定义,特殊函数类型,避免左、右值错误

		// Encapsulate it into a shared ptr in order to be able to copy construct // assign 
		//封装获取任务对象,方便另外一个线程查看结果

		auto task_ptr = std::make_shared<std::packaged_task<decltype(f(args...))()>>(func);

		// Wrap packaged task into void function
		//利用正则表达式,返回一个函数对象

		std::function<void()> wrapper_func = [task_ptr]() {
			(*task_ptr)();
		};

		// 队列通用安全封包函数,并压入安全队列

		m_queue.enqueue(wrapper_func);

		// 唤醒一个等待中的线程

		m_conditional_lock.notify_one();

		// 返回先前注册的任务指针

		return task_ptr->get_future();
	}
};

使用方法:

ThreadPool pool(数量);
pool.init();//初始化
for (size_t i = 2; i < 数量; i++)
{
	auto DoWork = [&](size_t i) -> void
	{
			this->do(i);
	};
	pool.submit(DoWork,i);
}
	
pool.shutdown();

猜你喜欢

转载自blog.csdn.net/fghler/article/details/107247355