基于C++写一个线程池

本文介绍了一个使用C++实现的线程池模板类,包括线程请求队列、工作线程、线程同步模块(互斥量、信号量)以及请求队列操作接口。线程池通过创建指定数量的工作线程来处理任务,当请求队列满时,新的请求将被拒绝。线程同步通过信号量和互斥量确保线程安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程池的设计大致需要包含这几部分:
线程请求队列(存放业务请求)、
工作线程(进行业务处理)、
线程同步模块(互斥量、信号量)
以及操作请求队列的接口(append)。
下面代码封装了一个简易的线程池,采用模板类进行实现

template<class T>
class threadpool
{
public:                                                                                                        
    //max_requests 请求队列中最多允许的、等待处理的请求的数量
    threadpool(Pool* connPool, int threadnum = 8, int max_request = 10000);
    ~threadpool();
    bool append_p(T* request); 	        //将事件放入请求队列

private:
    //工作线程函数, 不断从工作队列里面取任务
    static void* worker(void* arg);     //取任务, 调用run
    void run();  					    //执行任务

private:
    int m_thread_number; //线程池大小
    int m_max_requests;  //请求队列中允许的最大请求数量
    pthread_t* m_threads; //线程变量数组
    std::list<T*> m_workqueue; //请求队列
    locker m_queuelocker;  //保护请求队列
    sem m_queuestat;   //请求队列中的请求数信号量
    Pool* m_connPool;  //数据库连接
};  

具体实现:

template<class T>
threadpool<T>::threadpool(Pool* connPool, int threadnum, int max_request)
                         :m_connPool(connPool), m_thread_number(threadnum),
                          m_max_requests(max_request),m_threads(nullptr)
{
    if(threadnum <= 0 || max_request <= 0){
        throw std::exception();
    }
    m_threads = new pthread_t[m_thread_number]; //创建线程变量
    if(m_threads == nullptr){
        throw std::exception();
    }
    //接下来建立线程池
    for(int i = 0; i < m_thread_number; ++i){
        if(pthread_create(m_threads + i, NULL, worker, this) != 0){
            delete []m_threads; 
            throw std::exception();
        }
        if(pthread_detach(m_threads[i]) != 0){
            //使用detach分离线程, 该线程结束后资源自动回收, 无需join
            delete []m_threads;
            throw std::exception();
        }
    }
}

template<class T>
threadpool<T>::~threadpool(){
    //销毁线程池
    delete []m_threads;
}

template<class T>
bool threadpool<T>::append_p(T* request){
    m_queuelocker.lock();
    
    if(m_workqueue.size() >= m_max_requests){
        //请求队列已满
        m_queuelocker.unlock();
        return false;
    }
    m_workqueue.push_back(request); //将请求放入请求队列
    m_queuelocker.unlock();
    m_queuestat.post(); 		    //信号量+1
    return true;
}

template<class T>
void* threadpool<T>::worker(void* arg){
    threadpool* pool = (threadpool*)arg;
    pool->run();  //执行任务
    return pool;
}

template<class T>
void threadpool<T>::run(){
    while(true){
        m_queuestat.wait(); //如果无请求需要处理,阻塞在这里
        m_queuelocker.lock();
        if(m_workqueue.empty()){
            //没有任务可处理
            m_queuelocker.unlock();
            continue;
        }
        T* request = m_workqueue.front(); //取任务
        m_workqueue.pop_front();
        m_queuelocker.unlock(); 		  //下面不再操作共享任务队列, 解锁
        
        //下面就是进行业务的处理,可根据实际需求进行填补
}

同步机制实现:

class locker
{
public:
    locker(){
        if(pthread_mutex_init(&mtx, nullptr) != 0){
            throw std::exception();
        }
    }
    ~locker(){
        pthread_mutex_destroy(&mtx);
    }
    bool lock(){
        return pthread_mutex_lock(&mtx) == 0;
    }
    bool unlock(){
        return pthread_mutex_unlock(&mtx) == 0;
    }
    pthread_mutex_t* GetMtx(){ //获取一把锁
        return &mtx;
    }
private:
    pthread_mutex_t mtx;
};

class sem
{
public:
    sem(int num){
        if(sem_init(&id, 0, num) != 0){  //线程共享
            throw std::exception();  
        }
    }
    sem(){
        if(sem_init(&id, 0, 0) != 0){
            throw std::exception();
        }
    }
    ~sem(){
        sem_destroy(&id);
    }
    bool wait(){
        return sem_wait(&id) == 0;
    }
    bool post(){
        return sem_post(&id) == 0;
    }
private:
    sem_t id;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值