zoukankan      html  css  js  c++  java
  • C++11 条件变量

      C++11中的条件变量提供了用户等待的同步机制,在同步队列的应用中有很大的便利。

      简单同步队列代码如下(SimpleSyncQueue.h):

     1 #ifndef SIMPLESYNCQUEUE_H
     2 #define SIMPLESYNCQUEUE_H
     3 
     4 #include <thread>
     5 #include <condition_variable>
     6 #include <mutex>
     7 #include <list>
     8 #include <iostream>
     9 
    10 using namespace std;
    11 
    12 template<typename T>
    13 class SimpleSyncQueue
    14 {
    15 public:
    16     SimpleSyncQueue()
    17     {
    18 
    19     }
    20 
    21     void Put(const T& x)
    22     {
    23         //调用Put函数的线程获取互斥量,如果互斥量正在被占用,将等待
    24         std::lock_guard<std::mutex> lk(m_mutex);
    25 
    26         //保存数据
    27         m_queue.push_back(x);
    28 
    29         //通知等待m_notEmpty的线程
    30         m_notEmpty.notify_one();
    31     }
    32 
    33     void Take(T& x)
    34     {
    35         //调用Take函数的线程获取互斥量,如果互斥量正在被占用,将等待
    36         std::unique_lock<std::mutex> locker(m_mutex);
    37 
    38         m_notEmpty.wait(locker,[this] {
    39 
    40             if(m_queue.empty())
    41             {
    42                 cout<<"现在队列为空,请稍等"<<endl;
    43             }
    44 
    45             return !m_queue.empty();
    46         });
    47 
    48         x = m_queue.front();
    49         m_queue.pop_front();
    50     }
    51 
    52     bool Empty()
    53     {
    54         std::lock_guard<std::mutex> lk(m_mutex);
    55 
    56         return m_queue.empty();
    57     }
    58 
    59     size_t Size()
    60     {
    61         std::lock_guard<std::mutex> lk(m_mutex);
    62 
    63         return m_queue.size();
    64     }
    65 
    66 private:
    67     std::list<T> m_queue;   /* 用于等待的同步变量 */
    68     std::mutex m_mutex;     /* 用于多线程同步的互斥量 */
    69     std::condition_variable m_notEmpty; /* 用于等待的同步变量 */
    70 };
    71 
    72 
    73 
    74 #endif // SIMPLESYNCQUEUE_H
    View Code

      测试代码如下:

     1 #include <QCoreApplication>
     2 
     3 #include "simplesyncqueue.h"
     4 
     5 SimpleSyncQueue<int> testQueue;
     6 bool threadrun = true;
     7 
     8 void consumerthread()
     9 {
    10     int get;
    11 
    12     while(threadrun)
    13     {
    14         testQueue.Take(get);
    15 
    16         cout<<"consumer thread get: "<<get<<endl;
    17     }
    18 
    19     cout<<"consumerthread exit"<<endl;
    20 }
    21 
    22 void producerthread()
    23 {
    24     char in = 0;
    25 
    26     while(threadrun)
    27     {
    28         cin>>in;
    29 
    30         cout<<"user input: "<<in<<endl;
    31 
    32         switch(in)
    33         {
    34         case 'p':  testQueue.Put((int)100); break;
    35         case 'q':  threadrun = false; break;
    36         default:   break;
    37         }
    38     }
    39 
    40     cout<<"producerthread exit"<<endl;
    41 }
    42 
    43 int main(int argc, char *argv[])
    44 {
    45     QCoreApplication a(argc, argv);
    46 
    47     std::thread t1(consumerthread);
    48 
    49     std::thread t2(producerthread);
    50     t1.detach();
    51 
    52     t2.join();
    53 
    54     cout<<"program exit"<<endl;
    55 
    56     return a.exec();
    57 }
    View Code

      测试结果如下:  
          

      看看condition_variable类中的wait函数定义,参见http://en.cppreference.com/w/cpp/thread/condition_variable/wait

      

      关于这个函数,其实疑惑的是pred ()函数会被执行多少遍的问题。cppreference里的详解里给了一个 Equivalent to:

        while (!pred()) {
          wait(lock);
        }
       从Equivalent To可以看到pred开始被执行一次。
     
  • 相关阅读:
    获取Tekla属性方式
    基于C# 百度AI和科大汛飞语音合成SDK
    BIM工程信息管理系统-EF实体框架数据操作基类
    BIM工程信息管理新系统- 系统管理模块
    EChart绘制风速风向曲线分析图
    BIM工程信息管理系统-详细设计
    BIM工程信息管理系统搭建-系统功能需求
    基于C# 调用百度AI 人脸识别
    mago3DJS 应用
    Bitnami redmine windows环境下升级
  • 原文地址:https://www.cnblogs.com/kanite/p/9140903.html
Copyright © 2011-2022 走看看