c++11线程池

线程池的作用

避免大量的线程的创建和销毁,节约系统资源

线程池的分类

线程池的实现分为两类:

1)半同步半异步的线程池

2)领导者和追随者模式

参考:

https://blog.csdn.net/vjhghjghj/article/details/103956236?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-1&spm=1001.2101.3001.4242

半同步半异步的线程池

共分为3层,第一层,同步服务层,处理来自上层的任务请求,第二层是同步队列,第三层是:异步服务层

同步队列

功能:存储待处理的任务,交给线程池来处理。

实现:锁保证线程同步,条件变量实现线程通信,线程池空要等待,不空通知一个线程去处理;线程池满就等待,不满通知上层去添加新的任务。

#pragma once
#include<list>
#include<thread>
#include<condition_variable>
template<typename T>
class SyncQueue {
public:
    SyncQueue(const int maxSize):m_maxSize(maxSize),m_needStop(false){}
    bool notFull() {
        bool full = m_queue.size() >= m_maxSize;
        if (full)
            std::cout << "缓冲区满了,不能添加了" << std::endl;
        return !full;
    }
    bool notEmpty() {
        bool empty = m_queue.empty();
        return !empty();
    }
    template<typename F>
    void Add(F&& x) {
        std::unique_lock<std::mutex> locker(m_mutex);
        m_notFull.wait(locker, [this] {return m_needStop || notFull(); });
        if (m_needStop)
            return;
        m_queue.push_back(std::forward(x));
        m_notEmpty.notify_one();
    }
    
    void put(T&& x) {
        Add(std::forward(x));
    }
    void Take(std::list<T>& list) {
        std::unique_lock<std::mutex> locker(m_mutex);
        m_notEmpty.wait(locker, [this] {return m_needStop || notEmpty(); });
        if (m_needStop) {
            return;
        }
        list = std::move(m_queue);
        m_notFull.notify_one();
    }
    void Take(T& t) {
        std::unique_lock<std::mutex> locker(m_mutex);
        m_notEmpty.wait(locker, [this] {return m_needStop || notEmpty(); });
        if (m_needStop) {
            return;
        }
        t = m_queue.front();
        m_queue.pop_front();
        m_notFull.notify_one();
    }
    void Stop() {
        {
            std::lock_guard<std::mutex> locker(m_mutex);
            m_needStop = true;
        }
        m_notFull.notify_all();
        m_notEmpty.notify_all();
    }
    bool Empty() {
        
            std::lock_guard<std::mutex> locker(m_mutex);
            return m_queue.empty();
        
    }
    bool Full() {
        std::lock_guard<std::mutex> locker(m_mutex);
        return m_queue.size() == m_maxSize;
    }
    size_t Size() {
        std::lock_guard<std::mutex> locker(m_mutex);
        return m_queue.size() ;
    }
    size_t Count() {
        std::lock_guard<std::mutex> locker(m_mutex);
        return m_queue.size();
    }
    
private:
    std::list<T> m_queue;
    std::mutex m_mutex;
    std::condition_variable m_notEmpty;
    std::condition_variable m_notFull;
    int m_maxSize;
    bool m_needStop;
};
 

线程池实现

#pragma once
#include"syncQueue.h"
#include<functional>
#include<atomic>
const int MaxTaskCount = 10;
class ThreadPool {
public:
    using Task = std::function<void()>;
    ThreadPool(int numThreads=std::thread::hardware_concurrency()):m_queue(MaxTaskCount) {
        Start(numThreads);
    }
    ~ThreadPool()
    {
        Stop();
    }
    void Stop() {
        std::call_once(m_flag, [this] {StopThreadGroup(); });
    }
    void AddTask(Task&& task) {
        m_queue.put(std::forward<Task>(task));
    }
    void AddTask(const Task& task) {
        m_queue.put(task);
    }
private:
    void Start(int numThreads) {
        m_runing = true;
        for (int i = 0; i < numThreads; i++) {
            m_threadgroup.push_back(std::make_shared<std::thread>(&ThreadPool::RunInThread, this));
        }
    }
    void StopThreadGroup() {
        while (m_queue.notEmpty());
        m_queue.Stop();
        m_runing = false;
        for (auto thread : m_threadgroup) {
            if (thread)
                thread->join();
        }
        m_threadgroup.clear();
    }
    void RunInThread() {
        Task task;
        while (m_runing) {
            
            m_queue.Take(task);
            if (!m_runing)
                return;
            task();
            /*
            std::list<Task> list;
            m_queue.Take(list);
            std::cout <<"list.size:"<< list.size() << std::endl;
            for (auto& task : list) {
                if (!m_runing)
                    return;
                task();
            }
            */
        }
    }
    std::list<std::shared_ptr<std::thread>> m_threadgroup;
    SyncQueue<Task> m_queue;
    std::atomic_bool m_runing;
    std::once_flag m_flag;
};
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值