线程池技术简介
线程池是一种并发编程的技术,用于有效地管理和复用线程资源。它由一组预先创建的线程组成,这些线程可以在需要时执行任务,并在任务完成后返回线程池中等待下一个任务。
线程池的主要目的是避免反复创建和销毁线程的开销,以及有效地控制并发线程的数量。通过使用线程池,可以降低系统的负载,并提高任务执行的效率。
以下是线程池的一些关键特点:
- 线程池包含一个线程队列和任务队列,任务队列用于存储待执行的任务。
- 线程池在启动时会创建一定数量的线程,并将它们放入线程队列中。
- 当有任务需要执行时,线程池从任务队列中获取任务,并将其分配给空闲的线程执行。
- 执行完任务的线程会继续等待下一个任务的到来,而不是被销毁。
- 如果任务队列为空,线程池中的线程可以进入睡眠状态,减少资源占用。
- 线程池可以限制同时执行的线程数量,避免过多的并发线程导致系统负载过高。
手撕用
#include <bits/stdc++.h>
using namespace std;
class Thread_poolv3{
public:
Thread_poolv3(size_t thread_num = std::thread::hardware_concurrency()) : stop(false) {
if(thread_num == 0){
thread_num = 8;
}
vector_thread.reserve(thread_num);
for(size_t i = 0; i < thread_num; i++){
vector_thread.emplace_back([this](){this->work();});
}
}
void work(){
for(;;){
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(mtx);
condition.wait(lock, [this](){
return stop || !queue_task.empty();
});
if(stop && queue_task.empty()) return;
task = std::move(queue_task.front());
queue_task.pop();
}
task();
}
}
template <typename F, typename... Args>
void enqueue(F&& f, Args&&... args){
function<void()> task = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
{
std::lock_guard<std::mutex> lock(mtx);
queue_task.emplace(task);
}
condition.notify_one();
}
~Thread_poolv3(){
{
std::lock_guard<std::mutex> lock(mtx);
stop.store(true);
}
condition.notify_all();
for(auto& t : vector_thread){
if(t.joinable()){
t.join();
}
}
}
private:
std::atomic_bool stop;
size_t thread_num;
std::mutex mtx;
std::condition_variable condition;
std::vector<std::thread> vector_thread; // 线程队列 用向量表示
std::queue<function<void()>> queue_task; // 任务队列 用队列表示
};
void testTask(int id){
std::cout << "Executing task " << id << " on thread "<< std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(std::chrono::microseconds(200));
}
int main(){
Thread_poolv3 pool(4);
for(int i = 0; i < 10; i++){
pool.enqueue(testTask, i);
}
}