简单好用的threadPool (90行代码)【摘自改编于httplib源码】

时间:2023-04-07 15:00:06

今天在看cpp-httplib的源码, 发现其中的threadPool 线程词写的很简单, 而且很多的知识点,
直接把这部分代码摘抄出来,稍微改了一下,就能单独的使用并且跑起来了

全部实现如下 90行代码,复制出来0改动直接可使用
大家主要自己看下这块,思想和写法都不错,很简洁

#include <iostream>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <thread>
#include <list>

using Task = std::function<void()>;

class TaskQueue {
public:
	TaskQueue() = default;
	virtual ~TaskQueue() = default;

	virtual void enqueue(const Task&) = 0;
	virtual void shutdown() = 0;
};

class ThreadPool : public TaskQueue {
public:
	explicit ThreadPool(size_t n) {
		while (n)
		{
			m_threads.emplace_back(worker(*this));
			n--;
		}
	}

	ThreadPool(const ThreadPool&) = delete;
	~ThreadPool() override = default;

	void enqueue(const Task& task) override {
		{
			std::unique_lock<std::mutex> lock(m_mutex);
			m_tasks.push_back(task);
		}
		m_cond.notify_one();
	}

	void shutdown() override {
		{
			std::unique_lock<std::mutex> lock(m_mutex);
			m_shutdown = true;
		}

		m_cond.notify_all();

		for (auto& t : m_threads) {
			t.join();
		}
	}

private:
	struct worker {
		explicit worker(ThreadPool& pool) : m_pool(pool) {}

		void operator()() {
			for (;;) {
				Task task;
				{
					std::unique_lock<std::mutex> lock(m_pool.m_mutex);

					m_pool.m_cond.wait(
						lock, [&] {return !m_pool.m_tasks.empty() || m_pool.m_shutdown; }
					);

					if (m_pool.m_tasks.empty() && m_pool.m_shutdown)
						break;

					task = std::move(m_pool.m_tasks.front());
					m_pool.m_tasks.pop_front();
				}

				task();
			}
		}

		ThreadPool& m_pool;
	};
	friend struct worker;

private:
	bool m_shutdown = false;

	std::vector<std::thread> m_threads;
	std::list<Task> m_tasks;

	std::condition_variable m_cond;
	std::mutex m_mutex;
};

用例

/testcase/

void work1() {
	for (auto i = 0; i < 10000; i++)
		std::cout << "i am work1:" << i <<"threadId:"<< std::this_thread::get_id() << std::endl;
}

void work2() {

	for (auto i = 0; i < 10000; i++)
		std::cout << "i am work2:" << i << "threadId:" << std::this_thread::get_id() << std::endl;
}

void work3() {

	for (auto i = 0; i < 10000; i++)
		std::cout << "i am work3:" << i << "threadId:" << std::this_thread::get_id() << std::endl;
}

//

int main()
{
	TaskQueue* queue = new ThreadPool(3);
	queue->enqueue(work1);
	queue->enqueue(work2);
	queue->enqueue(work3);

	while (true) {}
	
	return 0;
}

运行图:
简单好用的threadPool (90行代码)【摘自改编于httplib源码】