基于std::mutex std::lock_guard std::condition_variable 和std::async实现的简单同步队列
C++多线程编程中通常会对共享的数据进行写保护,以防止多线程在对共享数据成员进行读写时造成资源争抢导致程序出现未定义的行为。通常的做法是在修改共享数据成员的时候进行加锁--mutex。在使用锁的时候通常是在对共享数据进行修改之前进行lock操作,在写完之后再进行unlock操作,进场会出现由于疏忽导致由于lock之后在离开共享成员操作区域时忘记unlock,导致死锁。
针对以上的问题,C++11中引入了std::unique_lock与std::lock_guard两种数据结构。通过对lock和unlock进行一次薄的封装,实现自动unlock的功能。std::unique_lock 与std::lock_guard都能实现自动加锁与解锁功能,但是std::unique_lock要比std::lock_guard更灵活,但是更灵活的代价是占用空间相对更大一点且相对更慢一点。
std::condition_variable 是条件变量,更多有关条件变量的定义参考维基百科。Linux 下使用 Pthread 库中的 pthread_cond_*() 函数提供了与条件变量相关的功能, Windows 则参考 MSDN。
当 std::condition_variable 对象的某个 wait 函数被调用的时候,它使用 std::unique_lock(通过 std::mutex) 来锁住当前线程。当前线程会一直被阻塞,直到另外一个线程在相同的 std::condition_variable 对象上调用了 notification 函数来唤醒当前线程。
std::condition_variable 对象通常使用 std::unique_lock<std::mutex> 来等待,如果需要使用另外的 lockable 类型,可以使用 std::condition_variable_any 类,本文后面会讲到 std::condition_variable_any 的用法。
template<typename T>
class SimpleSyncQueue
{
public:
SimpleSyncQueue(){}
~SimpleSyncQueue(){}
void Put(const T& element)
{
std::lock_guard<std::mutex> locker(m_mutex);
m_queue.push_back(element);
m_NotEmpty.notify_all();
}
void Take(T& result)
{
std::unique_lock<std::mutex> locker(m_mutex);
m_NotEmpty.wait(locker, [this](){cout << "take wait!" << endl; return !m_queue.empty(); });
result = m_queue.front();
m_queue.pop_front();
}
bool Empty()
{
std::lock_guard<std::mutex> locker(m_mutex);
return m_queue.empty();
}
size_t Size()
{
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;
}; SimpleSyncQueue<int> queue;
void Thread1func()
{
for (int i = ; i < ; i++)
{
queue.Put(i);
cout << "size: "<<queue.Size() << endl;
}
}
void Thread2func()
{
int res;
for (int i = ; i < ; i++)
{
queue.Take(res);
cout << "teke res: " << res << endl;
}
}
void Test14()
{
std::future<void> future1 = std::async(std::launch::async,Thread1func);
//Sleep(1000);
std::future<void> future2 = std::async(std::launch::async, Thread2func);
future1.wait();
future2.wait();
} 某次执行结果如下:
基于std::mutex std::lock_guard std::condition_variable 和std::async实现的简单同步队列的更多相关文章
- 【C/C++开发】C++11 并发指南三(std::mutex 详解)
		
本系列文章主要介绍 C++11 并发编程,计划分为 9 章介绍 C++11 的并发和多线程编程,分别如下: C++11 并发指南一(C++11 多线程初探)(本章计划 1-2 篇,已完成 1 篇) C ...
 - C++11 并发指南三(std::mutex 详解)
		
上一篇<C++11 并发指南二(std::thread 详解)>中主要讲到了 std::thread 的一些用法,并给出了两个小例子,本文将介绍 std::mutex 的用法. Mutex ...
 - C++11并发——多线程std::mutex (二)
		
https://www.cnblogs.com/haippy/p/3237213.html Mutex 又称互斥量,C++ 11中与 Mutex 相关的类(包括锁类型)和函数都声明在 <mute ...
 - C++11 并发指南三(std::mutex 详解)(转)
		
转自:http://www.cnblogs.com/haippy/p/3237213.html 上一篇<C++11 并发指南二(std::thread 详解)>中主要讲到了 std::th ...
 - 使用std::mutex取代QMutex
		
为了保证对某个资源的操作是原子性的(对资源读写时,只有当前的操作结束,才允许另外线程对其操作,这里有个理解误区,资源操作原子性不是说,当前某个线程获得了某个资源使用权,然后线程执行时间完毕,要切换线程 ...
 - C++11并发之std::mutex
		
知识链接: C++11并发之std::thread 本文概要: 1. 头文件. 2.std::mutex. 3.std::recursive_mutex. 4.std::time_mutex. 5 ...
 - C++11的mutex和lock_guard,muduo的MutexLock 与MutexLockGuard
		
互斥锁是用来保护一段临界区的,它可以保证某段时间内只有一个线程在执行一段代码或者访问某个资源. C++11的mutex和lock_guard C++11新增了mutex,使用方法和linux底下的常用 ...
 - C++11:基于std::queue和std::mutex构建一个线程安全的队列
		
C++11:基于std::queue和std::mutex构建一个线程安全的队列 C++中的模板std::queue提供了一个队列容器,但这个容器并不是线程安全的,如果在多线程环境下使用队列,它是不能 ...
 - C++11 并发之std::thread   std::mutex
		
https://www.cnblogs.com/whlook/p/6573659.html (https://www.cnblogs.com/lidabo/p/7852033.html) C++:线程 ...
 
随机推荐
- BZOJ 2200--[Usaco2011 Jan]道路和航线(最短路&拓扑排序)
			
2200: [Usaco2011 Jan]道路和航线 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1128 Solved: 414[Submit] ...
 - python 通过pytz模块进行时区的转换,获取指定时区的时间
			
import pytz import time import datetime print(pytz.country_timezones('cn')) # 查询中国所拥有的时区 print(pytz. ...
 - 讲讲我当年是怎么拿到AI研发公司offer的
			
前言 很多的老铁私信问我,当年我是怎么拿到公司offer的,我记得我毕业是2015年,那时人工智能这个行业还没热起来,能提供的岗位很少但是面试的人更少,我又是本专业毕业的,所以当初找工作还算顺利,去面 ...
 - sudoer命令各参数含义及设置
			
对于普通用户sudo加权的时限制可以执行的命令 https://segmentfault.com/a/1190000007394449 需要修改/etc/sudoers 1. 字段说明如下 授权用户/ ...
 - 基于iview的后台管理
			
年前由于时间紧迫,原本使用iview技术开发后台管理系统的大神另有任务,我中途接手该项目,此前对于iview一无所知的我是一脸的懵逼,好在后台管理的整体框架大神已经搭建好了,而我之前对vue也有一定的 ...
 - 浏览器内核、渲染引擎、JS引擎简介
			
一.定义 浏览器内核分成两部分:渲染引擎和JS引擎. 由于JS引擎越来越独立,浏览器内核 就倾向于 单指 渲染引擎. 渲染引擎是一种对HTML文档进行解析并将其显示在页面上的工具.(说白了,就是按照 ...
 - 在Ubuntu 16.04上利用Jexus+.Net Core+Linux版SQL Server部署ZKEACMS.Core
			
百度传课视频地址:https://chuanke.baidu.com/v5849090-223278-1498090.html 一.SQL Server on Linux的安装 官方文档:https: ...
 - android开发学习——day6
			
关于UI的几个插件学习 button和textview,以及点击button利用Toast提醒,editText private EditText editText; @Override protec ...
 - PHP使用APC获取上传文件进度
			
今天发现使用PHP的APC也能获取上传文件的进度.这篇文章就说下如何做. 安装APC 首先安装APC的方法和其他PHP模块的方法没什么两样,网上能找出好多 phpinfo可以看到APC的默认配置有: ...
 - Redis学习系列三List列表
			
一.简介 Redis中的列表相当于C#中的LinkedList,也就是链表,如果你研究过链表这个数据结构,肯定知道.它的插入和删除是非常快的,但是定位却很慢,因为必须遍历所有的元素,才能找到对应的值, ...
 
			
		