基于C++11实现的线程池,任务队列满和池中线程满时做了简单处理

在我们进行实际编程时,经常会碰到数量级大、耗时长的任务,尤其在网络服务中,可能有几万个用户同时访问你的服务器,不可能进来一个用户我们就开辟一个线程,这样做的后果是当用户量大的时候线程数量过多,线程间的调度效率就很低下了,反而会影响程序的效率。因此这时候,我们可以通过线程池,对一定数量的线程进行复用,提高应用的效率。线程池的结构是根据设计模式中的生产者消费者模式进行设计的,感兴趣的朋友可以百度学习一下。
这几天看了网上几篇的线程池实现代码,本篇文章主要参考以下博客内容:

https://www.jianshu.com/p/eec63026f8d0

上面这篇博客基于C++11新特性用100行代码实现了线程池,代码比较简洁易读,但是没有对任务队列的最大数量进行限制,以及在线程池中线程空闲线程为0时没有相应的处理。
本文主要根据参考博客实现以下功能:
1.管理一定数量的线程,当有任务commit进来的时候,唤醒池中的线程处理任务。
2.当线程池中空闲线程为0时,等待其他线程处理完毕,再进行线程唤醒
3.对任务队列最大数量进行限制,当任务队列满时,阻塞commit函数调用的线程

具体代码如下,代码中基本每一行都加了注释:

#include <vector>
#include <queue>
#include <thread>
#include <atomic>
#include <condition_variable>
#include <future>
#include <functional>
#include <stdexcept>
#include <QDebug>
#include <iostream>
#include <omp.h>
class threadpool
{
   
   
private:
    using Task = std::function<void()>; //using 相当于typedef
    std::vector<std::thread> m_threads;
    std::queue<Task> m_tasks;  //任务队列
    std::mutex m_lock;
    std::condition_variable m_cvTask; //条件变量
    std::atomic<bool> m_stoped; //是否关闭提交 std::atomic<T> 对于对象的操作都是原子的不用加锁
    std::atomic<int>  m_idlThrNum; //空闲线程数量
    //std::atomic<bool> m_stoped;
    std::atomic<int>  m_taskNum;
    std::atomic<int>  m_maxTaskNum;  //任务队列的最大任务数量
public:
    inline threadpool(unsigned short size = 4,int maxTask = 500) :m_stoped(false)
    {
   
   
        m_idlThrNum = size < 1 ? 1 : size; //如果传入的构造线程数量为1以下,那默认为1
        m_maxTaskNum= maxTask< 1 ? 1 : maxTask;
        m_taskNum.store(0);
        for (size = 0; size < m_idlThrNum; ++size)
        {
   
   
            m_threads.emplace_back([this]{
   
   
                while(!this->m_stoped)//如果关闭为假,执行循环
                {
   
   
                    Task task;
                    {
   
   
                        std::unique_lock<std::mutex> lock(this->m_lock);
                        this->m_cvTask.wait(lock,[this]{
   
   
                            //当停止为真或者任务队列不为空时信号量触发,取消阻塞状态
                            return this->m_stoped.load() || !this->m_tasks.empty();
                        });
                        //当信号量触发前一直阻塞在这里
                        if(this->m_stoped && this->m_tasks.empty())
                            return;//当触发线程池停止时,任务队列也为空,就结束线程
                        task = std::move(this->m_tasks.front()); // 取一个 task
                        this->m_tasks.pop(
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值