// ConsoleApplication6.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<thread>
#include<iostream>
#include<list>
#include<mutex>
using namespace std;
mutex mut_one;
once_flag gl_flag;//标记 class A
{
private:
list<int> msgRecvQueue;
mutex my_mutex;

my_cond;//生成一个条件对象
static A* Instance;
public:
static A* GetInstance()
{
if (Instance == NULL)
{
unique_lock<mutex> my(mut_one);
if (Instance == NULL)
{
Instance = new A;
static A_Guard gl;
}
}
return Instance;
} class A_Guard
{
public:
~A_Guard()
{
if (A::Instance != NULL)
{
delete A::Instance;
A::Instance = NULL;
}
}
};
void enmsg()
{
for (int i = 1; i <= 100; i++)
{
msgRecvQueue.push_back(i);
cout << "压入数据成功,数据为:" << i << endl;
my_cond.notify_one();//作用是为了唤醒堵塞的wait
}
} void outmsg()
{
int command = 0;
while (true)
{
unique_lock<mutex> sbg(my_mutex);
my_cond.wait(sbg, [this] {
if (!msgRecvQueue.empty())
return true;
else
return false;
});//第二个参数如果返回false,wait会解锁,并堵塞在这一行等待notify_one
//上面假设notify_one执行了唤醒的操作,那么第二个参数里面的list就不为空了,会返回true,
//返回true之后也就意味着不堵塞了,继续执行以下的代码
command = msgRecvQueue.front();
cout << "弹出来的数据是" << command << endl;
msgRecvQueue.pop_front();
}
} }; A* A::Instance = NULL;
void Thread_one()
{
A *s = A::GetInstance();
s->enmsg();
}
void Thread_two()
{
A*s = A::GetInstance();
s->outmsg();
}
int main()
{ thread thone(Thread_one);
thread thtwo(Thread_two);
thone.join();
thtwo.join(); return 0;
}

把notify_one变为notify_all的代码:

// ConsoleApplication6.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<thread>
#include<iostream>
#include<list>
#include<mutex>
using namespace std;
mutex mut_one;
once_flag gl_flag;//标记 class A
{
private:
list<int> msgRecvQueue;
mutex my_mutex;
condition_variable my_cond;//生成一个条件对象
static A* Instance;
public:
static A* GetInstance()
{
if (Instance == NULL)
{
unique_lock<mutex> my(mut_one);
if (Instance == NULL)
{
Instance = new A;
static A_Guard gl;
}
}
return Instance;
} class A_Guard
{
public:
~A_Guard()
{
if (A::Instance != NULL)
{
delete A::Instance;
A::Instance = NULL;
}
}
};
void enmsg()
{
for (int i = 1; i <= 100; i++)
{
msgRecvQueue.push_back(i);
cout << "压入数据成功,数据为:" << i << endl;
//my_cond.notify_one();//作用是为了唤醒堵塞的wait
my_cond.notify_all();//故名思意,唤醒的不知一个wait
}
} void outmsg()
{
int command = 0;
while (true)
{
unique_lock<mutex> sbg(my_mutex);
my_cond.wait(sbg, [this] {
if (!msgRecvQueue.empty())
return true;
else
return false;
});//第二个参数如果返回false,wait会解锁,并堵塞在这一行等待notify_one
//上面假设notify_one执行了唤醒的操作,那么第二个参数里面的list就不为空了,会返回true,
//返回true之后也就意味着不堵塞了,继续执行以下的代码
command = msgRecvQueue.front();
cout << "弹出来的数据是" << command << endl;
msgRecvQueue.pop_front();
}
} }; A* A::Instance = NULL;
void Thread_one()
{
A *s = A::GetInstance();
s->enmsg();
}
void Thread_two()
{
A*s = A::GetInstance();
s->outmsg();
}
void Thread_three()
{
A*s = A::GetInstance();
s->outmsg();
}
int main()
{ thread thone(Thread_one);
thread thtwo(Thread_two);
thread three(Thread_three);
thone.join();
thtwo.join();
three.join();
return 0;
}

把其中的一部分拿出来分析一下,比如这段代码:

while (true)
{
unique_lock<mutex> sbg(my_mutex);
my_cond.wait(sbg, [this] {
if (!msgRecvQueue.empty())
return true;
else
return false;
});//第二个参数如果返回false,wait会解锁,并堵塞在这一行等待notify_one
//上面假设notify_one执行了唤醒的操作,那么第二个参数里面的list就不为空了,会返回true,
//返回true之后也就意味着不堵塞了,继续执行以下的代码
command = msgRecvQueue.front();
cout << "弹出来的数据是" << command << endl;
msgRecvQueue.pop_front();
}

变为:

    while (true)
{
unique_lock<mutex> sbg(my_mutex);
my_cond.wait(sbg, [this] {
if (!msgRecvQueue.empty())
return true;
else
return false;
});//第二个参数如果返回false,wait会解锁,并堵塞在这一行等待notify_one
//上面假设notify_one执行了唤醒的操作,那么第二个参数里面的list就不为空了,会返回true,
//返回true之后也就意味着不堵塞了,继续执行以下的代码 sbg.unlock();//把锁打开了
chrono::milliseconds dura(2000);
this_thread::sleep_for(dura);
command = msgRecvQueue.front();
cout << "弹出来的数据是" << command << endl;
msgRecvQueue.pop_front();
}

未完

最新文章

  1. LeetCode - 54. Spiral Matrix
  2. PAT 1026. 程序运行时间(15)
  3. php 安装pdo_mysql 扩展
  4. windows下tomcat切割日志按照日期输出
  5. 如何在DJANGO里,向有外键(一对多和多对多)的DB里插入数据?
  6. hadoop-0.20-集群搭建___实体机通过SSH访问基于VM安装的Linux
  7. 简单的html5 File base64 图片上传
  8. 数据库分库分表(sharding)系列(一)拆分实施策略和示例演示
  9. Autofac创建实例的方法总结 【转】
  10. 基于visual Studio2013解决C语言竞赛题之0520相邻元素
  11. SSO(Single Sign On)系列(一)--SSO简单介绍
  12. FineReport破解心得
  13. Schedule Problem spfa 差分约束
  14. Dynamics CRM图表高级话题:创建跨实体的图表
  15. IDEA快速入门(Mac版)
  16. Java语法之注解
  17. Iterator迭代器快捷键
  18. Windows下如何正确下载并安装可视化的Redis数据库管理工具(redis-desktop-manager)(图文详解)
  19. cmake和make区别
  20. android之键盘转载

热门文章

  1. Qt5获取可用串口
  2. c++内存分布之虚析构函数
  3. 【LeetCode】323. Number of Connected Components in an Undirected Graph 解题报告 (C++)
  4. 【LeetCode】136. Single Number 解题报告(Java & Python)
  5. 【LeetCode】777. Swap Adjacent in LR String 解题报告(Python)
  6. 1046:Square Number
  7. The Best Path
  8. 【C++】关键字回忆leetcode题解
  9. 第六个知识点:我们怎么把NP问题解释成一组可以在多项式内证明的命题
  10. jsoncpp转换字符串