V1版本和V2版本不存在哪个更好,需要区分不同场景,使用不同的线程池,以及线程池更多功能增加,当前只是简单实现功能。
下面这个线程池使用了一个任务队列来保存需要执行的任务,并在有新任务时通知线程池中的线程进行执行。在pushTask
函数中,我们接受一个可调用的任务,将其封装为std::function<void()>
类型,并将其添加到任务队列中。工作线程从任务队列中取出任务并执行,直到收到停止信号或任务队列为空。
在示例用法中,创建了一个拥有10个线程的线程池,并将两个任务提交给线程池进行执行。每个任务都是使用lambda表达式来表示,并可以使用参数传递数据。
废话少说,直接show code!
线程池类声明
#pragma once
#include<iostream>
#include<thread>
#include<deque>
#include<functional>
#include<condition_variable>
#include<mutex>
#include<vector>
class threadPool{
public:
threadPool(int threadNum);
~threadPool();
template<typename F, typename... Args>
void pushTask(F&& f,Args&&... args);
private:
std::vector<std::thread> m_threads;
std::deque<std::function<void()>> m_task_queue;
std::mutex m_thread_lock;
std::condition_variable m_cv;
bool m_stop;
};
线程池类定义
#include"threadPoolv2.h"
threadPool::threadPool(int threadNum):m_stop(false)
{
for(int i = 0;i < threadNum;i++)
{
m_threads.emplace_back(
std::thread([this]{
while(true)
{
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(m_thread_lock);
m_cv.wait(lock,[this]{return m_stop || !m_task_queue.empty();});
task = std::move(m_task_queue.front());
m_task_queue.pop_front();
}
task();
}
})
);
}
};
threadPool::~threadPool()
{
{
std::unique_lock<std::mutex> lock(m_thread_lock);
m_stop = true;
}
m_cv.notify_all();
for(auto& t : m_threads)
{
t.join();
}
}
template<typename F, typename... Args>
void threadPool::pushTask(F&& f,Args&&... args)
{
std::function<void()> task = std::bind(std::forward<F>(f),std::forward<Args>(arg));
{
std::unique_lock<std::mutex> lock(m_thread_lock);
m_task_queue.push_front(task);
}
m_cv.notify_one();
}
调用举例
#include"threadPoolv2.h"
int main()
{
threadPool threadP(10);
threadP.pushTask([](int a ,int b){
std::cout << "a+b:" << a+b << std::endl;
},10,20);
threadP.pushTask([]{
for(int i = 0;i < 5 ;i++)
{
std::cout << "i:" << i << std::endl;
}
});
return 0;
}