• c++11 线程池学习笔记 (一) 任务队列


    学习内容来自一下地址

    http://www.cnblogs.com/qicosmos/p/4772486.html

    github https://github.com/qicosmos/cosmos

    主要使用c++11的多线程编程的互斥 同步等功能 编写一个生产消费者队列 用于任务的传递

    将任务的接受处理进行分离 更加简洁 易于处理和扩展修改

    template<typename T> //队列传递的元素  为了适配更多情况 这里使用了模板
    class SyncQueue {
    ...................
    }

     

    //初始化函数 定义队列最大可容纳元素数目和停止表示

    SyncQueue(int maxSize):m_maxSize(maxSize),m_needStop(false){}

    //Put函数即是提价元素 之所以使用两种函数 是考虑左值和右值 提高元素拷贝效率

    void Put(const T& x) {
    Add(x);
    }
    void Put(T&& x) {
    Add(std::forward<T>(x));
    }

    //查看Add函数

    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<F>(x));  //则将元素添加进容器
    m_notEmpty.notify_one();
    }
    //加锁情况下 使条件变量等待 队列未满或者标记停止标识 则将元素添加进容器或者停止退出

    //元素取出函数 一个是取出容器内全部元素 一个是取出单个元素

    void Take(std::list<T>& list) 

    void Take(T& t) 

    //void Take(std::list<T>& list) 取出容器内全部元素 直接将容器去除 并清除队列内的容器

    //代码里直接使用了move函数  并notify Take函数中的条件变量

    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) 加锁情况下 使用条件变量等待停止标识或者容器非空
    //将容器内元素弹出 并notify Add函数中的条件变量

    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();
    }

    源码如下 (仅仅队列代码,测试代码将同线程池一同测试)

     1 #pragma once
     2 
     3 #include <list>
     4 #include <mutex>
     5 #include <thread>
     6 #include <condition_variable>
     7 #include <iostream>
     8 
     9 using namespace std;
    10 
    11 template<typename T>
    12 class SyncQueue {
    13 public:
    14     SyncQueue(int maxSize):m_maxSize(maxSize),m_needStop(false){}
    15     void Put(const T& x) {
    16         Add(x);
    17     }
    18     void Put(T&& x) {
    19         Add(std::forward<T>(x));
    20     }
    21     void Take(std::list<T>& list) {
    22         std::unique_lock<std::mutex> locker(m_mutex);
    23         m_notEmpty.wait(locker, [this] {return m_needStop || NotEmpty(); });
    24         if (m_needStop)
    25             return;
    26         list = std::move(m_queue);
    27         m_notFull.notify_one();
    28     }
    29 
    30     void Take(T& t) {
    31         std::unique_lock<std::mutex> locker(m_mutex);
    32         m_notEmpty.wait(locker, [this] {return m_needStop || NotEmpty(); });
    33         if (m_needStop)
    34             return;
    35         t = m_queue.front();
    36         m_queue.pop_front();
    37         m_notFull.notify_one();
    38     }
    39 
    40     void Stop() {
    41         {
    42             std::lock_guard<std::mutex> locker(m_mutex);
    43             m_needStop = true;
    44         }
    45         m_notFull.notify_all();
    46         m_notEmpty.notify_all();
    47     }
    48 
    49     bool Empty() {
    50         std::lock_guard<std::mutex> locker(m_mutex);
    51         return m_queue.empty();
    52     }
    53 
    54     bool Full() {
    55         std::lock_guard<std::mutex> locker(m_mutex);
    56         return m_queue.size() == m_maxSize;
    57     }
    58 
    59     size_t Size() {
    60         std::lock_guard<std::mutex> locker(m_mutex);
    61         return m_queue.size();
    62     }
    63 
    64     int Count() {
    65         return m_queue.size();
    66     }
    67 private:
    68     bool NotFull()const {
    69         bool full = m_queue.size() >= m_maxSize;
    70         if (full)
    71             cout << "buffer area is full,wait..." << endl;
    72         return !full;
    73     }
    74     bool NotEmpty()const {
    75         bool empty = m_queue.empty();
    76         if (empty)
    77             cout << "buffer area is empty,wait... " << 
    78                 " threadID: " << this_thread::get_id() <<endl;
    79         return !empty;
    80     }
    81 
    82     template<typename F>
    83     void Add(F&& x) {
    84         std::unique_lock<std::mutex> locker(m_mutex);
    85         m_notFull.wait(locker, [this] {return m_needStop || NotFull(); });
    86         if (m_needStop)
    87             return;
    88         m_queue.push_back(std::forward<F>(x));
    89         m_notEmpty.notify_one();
    90     }
    91 private:
    92     std::list<T> m_queue;
    93     std::mutex m_mutex;
    94     std::condition_variable m_notEmpty;
    95     std::condition_variable m_notFull;
    96     int m_maxSize;
    97     bool m_needStop;
    98 };
    View Code
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    两路归并算法
    个性化搜索引擎调研(三)
    编程珠玑开篇磁盘文件排序问题
    Lucene里经常被聊到的几个话题
    成就霸业的座右铭(绝对经典)
    别人对你的态度,决定了你的命运
    iBATIS缓存实现分析[转]
    Taste/Thoth:Taste Architecture 概览【转Beyond Search】
    中文分词算法笔记
    ConcurrentModificationException主要原因及处理方法
  • 原文地址:https://www.cnblogs.com/itdef/p/8454389.html
Copyright © 2020-2023  润新知