今天在看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;
}
运行图: