基于指针的线程池

使用原线程池 当 push 和 pop的对象过大时,消耗时延过高,需优化线程池

采用 std::move()+ unique_ptr的方法,能极大的减少时延,

实际就是避免了多次拷贝,直接使用指针。

代码实现

ThreadPool

cpp 复制代码
#ifndef _THREAD_TOOL_H_
#define _THREAD_TOOL_H_

#include<iostream>
#include<pthread.h>
#include<queue>
#include<ctime>
#include<cstdlib>
#include<Tools/Misc.h>
#include<deque>
#include<memory>  
#define NUM 5
using namespace std;

template<class T>
class ThreadPool
{
public:
    ThreadPool(int cap = NUM) : thread_num(cap)
    {
        pthread_mutex_init(&_lock, nullptr);
        pthread_cond_init(&_cond, nullptr);
    }

    void LockQueue()
    {
        pthread_mutex_lock(&_lock);
    }

    void UnlockQueue()
    {
        pthread_mutex_unlock(&_lock);
    }

    void Wait()
    {
        pthread_cond_wait(&_cond, &_lock);
    }

    void Wake()
    {
        pthread_cond_signal(&_cond);
    }

    bool isQueueEmpty()
    {
        return _task_queue.size() == 0 ? true : false;
    }

    static void* Rountine(void *arg)
    {
        pthread_detach(pthread_self());
        ThreadPool* self = (ThreadPool*)arg;

        while (true)
        {
            self->LockQueue();
            while (self->isQueueEmpty()) //避免被虚假唤醒
            {
                self->Wait();
            }

            std::unique_ptr<T> t;
            self->Pop(t);
            self->UnlockQueue();

            // 执行任务
            t->run();
        }
    }

    void Thread_pool_init()
    {
        pthread_t tids[thread_num];

        for (int i = 0; i < thread_num; i++)
        {
            pthread_create(&tids[i], nullptr, Rountine, this);
        }
    }

    void push(std::unique_ptr<T>&& in)
    {
        LockQueue();
        _task_queue.push_back(std::move(in));  // 使用 move 将任务指针传入队列
        Wake();
        UnlockQueue();
    }

    // Pop 时返回 unique_ptr<T> 类型的任务指针
    void Pop(std::unique_ptr<T>& out)
    {
        out = std::move(_task_queue.front());
        _task_queue.pop_front();
    }

    ~ThreadPool()
    {
        pthread_mutex_destroy(&_lock);
        pthread_cond_destroy(&_cond);
    }

private:
    pthread_mutex_t _lock;
    pthread_cond_t _cond;
    deque<std::unique_ptr<T>> _task_queue;  // 存储智能指针
    int thread_num;
};

#endif

task 任务

cpp 复制代码
#ifndef __TASK__H_
#define __TASK__H_
 
#include <iostream>
#include <functional>
#include <thread>
#include <chrono>



#include <iostream>
#include <utility> 

template<class T>
class Task 
{
public:
    Task() {
        executeFunc = nullptr;
    }

    Task(void(*func)(T), T data)
        : executeFunc(func), _data(std::move(data)) {}

    Task(const Task<T>& other)
        : executeFunc(other.executeFunc), _data(other._data) {}

    ~Task() = default;
    
    Task<T>& operator=(Task<T> other) 
    {  
        std::swap(executeFunc, other.executeFunc);
        std::swap(_data, other._data);
        return *this;
    }

    void run() 
    {
        if (executeFunc) 
        {
            executeFunc(_data);
        }
    }

public:
    void (*executeFunc)(T);
    T _data;
};


#endif

main.cc

cpp 复制代码
#include "task.h"
#include "ThreadPool.hpp"
#include <stdio.h>
#include <random>

#define TASK_NUM 10

static void DoJob(vector<int> data)
{
    for(int i =0 ;i< data.size(); i++)
    {
        printf("data = %d ", data[i]);
    }
    printf("\n");
}

int main()
{
    
    uint16_t num_threads = std::thread::hardware_concurrency();
    printf("thread_nums %d\n", num_threads);

    std::unique_ptr<ThreadPool<Task<vector<int>>>> tp(new ThreadPool<Task<vector<int>>>(num_threads));
    tp->Thread_pool_init();

    std::vector<int> v1;
    std::random_device rd;
    std::mt19937 gen(rd());
    // 定义范围
    int min = 10;
    int max = 50;
    while(true)
    {
        // 定义均匀分布
        std::uniform_int_distribution<> dis(min, max);

        // 生成随机数
        int random_number = dis(gen);
        v1.push_back(random_number);

        if(v1.size() == TASK_NUM)
        {
            auto task = std::make_unique<Task<std::vector<int>>>(DoJob, std::move(v1));
            tp->push(std::move(task));
        }

    }


    return 0;
}

此线程池 可以极大的减少拷贝,降低时延,并根据当前硬件的核数,开启对应的线程数量。

相关推荐
Magnum Lehar14 分钟前
3d游戏引擎EngineTest的系统实现3
java·开发语言·游戏引擎
Mcworld85729 分钟前
java集合
java·开发语言·windows
成功人chen某30 分钟前
配置VScodePython环境Python was not found;
开发语言·python
wuqingshun3141591 小时前
蓝桥杯 16. 外卖店优先级
c++·算法·职场和发展·蓝桥杯·深度优先
海绵宝宝贾克斯儿1 小时前
C++中如何实现一个单例模式?
开发语言·c++·单例模式
史迪仔01121 小时前
[python] Python单例模式:__new__与线程安全解析
开发语言·python·单例模式
Epiphany.5562 小时前
素数筛(欧拉筛算法)
c++·算法·图论
龙湾开发2 小时前
计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 10.增强表面细节(二)法线贴图
c++·笔记·学习·图形渲染·贴图
whoarethenext2 小时前
c/c++的opencv的轮廓匹配初识
c语言·c++·opencv
爱吃涮毛肚的肥肥(暂时吃不了版)2 小时前
项目班——0510——JSON网络封装
c++·算法·json