C++11 线程同步接口std::condition_variable和std::future的简单使用
std::condition_variable
条件变量std::condition_variable有wait和notify接口用于线程间的同步。如下图所示,Thread 2阻塞在wait接口,Thread 1通过notify接口通知Thread 2继续执行。

具体参见示例代码:
#include<iostream>
#include<mutex>
#include<thread>
#include<queue>
std::mutex mt;
std::queue<int> data;
std::condition_variable cv;
auto start=std::chrono::high_resolution_clock::now();
void logCurrentTime()
{
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << elapsed << ":";
}
void prepare_data()
{
logCurrentTime();
std::cout << "this is " << __FUNCTION__ << " thread:" << std::this_thread::get_id() << std::endl;
for (int i = 0; i < 10; i++)
{
data.push(i);
logCurrentTime();
std::cout << "data OK:" << i << std::endl;
}
//start to notify consume_data thread data is OK!
cv.notify_one();
}
void consume_data()
{
logCurrentTime();
std::cout << "this is: " << __FUNCTION__ << " thread:" << std::this_thread::get_id() << std::endl;
std::unique_lock<std::mutex> lk(mt);
//wait first for notification
cv.wait(lk); //it must accept a unique_lock parameter to wait
while (!data.empty())
{
logCurrentTime();
std::cout << "data consumed: " << data.front() << std::endl;
data.pop();
}
}
int main()
{
std::thread t2(consume_data);
//wait for a while to wait first then prepare data,otherwise stuck on wait
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::thread t1(prepare_data);
t1.join();
t2.join();
return 0;
}
输出结果

分析
主线程中另启两个线程,分别执行consume_data和prepare_data,其中consume_data要先执行,以保证先等待再通知,否则若先通知再等待就死锁了。首先consume_data线程在从wait 处阻塞等待。后prepare_data线程中依次向队列写入0-10,写完之后通过notify_one 通知consume_data线程解除阻塞,依次读取0-10。
std::future
std::future与std::async配合异步执行代码,再通过wait或get接口阻塞当前线程等待结果。如下图所示,Thread 2中future接口的get或wait接口会阻塞当前线程,std::async异步开启的新线程Thread1执行结束后,将结果存于std::future后通知Thread 1获取结果后继续执行.

具体参见如下代码:
#include <iostream>
#include <future>
#include<thread>
int test()
{
std::cout << "this is " << __FUNCTION__ << " thread:" << std::this_thread::get_id() << std::endl;;
std::this_thread::sleep_for(std::chrono::microseconds(1000));
return 10;
}
int main()
{
std::cout << "this is " <<__FUNCTION__<<" thread:" << std::this_thread::get_id() << std::endl;;
//this will lanuch on another thread
std::future<int> result = std::async(test);
std::cout << "After lanuch a thread: "<< std::this_thread::get_id() << std::endl;
//block the thread and wait for the result
std::cout << "result is: " <<result.get()<< std::endl;
std::cout << "After get result "<< std::endl;
return 0;
}
输出结果

分析
主程序中调用std::async异步调用test函数,可以看到main函数的线程ID 27428与test函数执行的线程ID 9704并不一样,说明std::async另起了一个新的线程。在test线程中,先sleep 1000ms,所以可以看到"After lanuch a thread:"先输出,说明主线程异步执行,不受子线程影响。而"After get result "最后输出,说明get()方法会阻塞主线程,直到获取结果。
C++11 线程同步接口std::condition_variable和std::future的简单使用的更多相关文章
- 基于std::mutex std::lock_guard std::condition_variable 和std::async实现的简单同步队列
C++多线程编程中通常会对共享的数据进行写保护,以防止多线程在对共享数据成员进行读写时造成资源争抢导致程序出现未定义的行为.通常的做法是在修改共享数据成员的时候进行加锁--mutex.在使用锁的时候通 ...
- APUE学习笔记——11 线程同步、互斥锁、自旋锁、条件变量
线程同步 同属于一个进程的不同线程是共享内存的,因而在执行过程中需要考虑数据的一致性. 假设:进程有一变量i=0,线程A执行i++,线程B执行i++,那么最终i的取值是多少呢?似乎一定 ...
- 第30课 线程同步(std::condition_variable)
一. 条件变量 (一)条件变量概述 多线程访问一个共享资源(或称临界区),不仅需要用互斥锁实现独享访问避免并发错误,在获得互斥锁进入临界区后,还需检查特定条件是否成立.当某个线程修改测试条件后,将通知 ...
- C++11并发——多线程条件变量std::condition_variable(四)
https://www.jianshu.com/p/a31d4fb5594f https://blog.csdn.net/y396397735/article/details/81272752 htt ...
- C++11 并发指南五(std::condition_variable 详解)
前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread,std::mut ...
- 转 C++11 并发指南std::condition_variable详解
之前看过,但是一直没有怎么用就忘了,转一篇别人的文字记录下来 本文将介绍 C++11 标准中 <condition_variable> 头文件里面的类和相关函数. <conditio ...
- C++11 并发指南五(std::condition_variable 详解)(转)
前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread,std::mut ...
- 【转】C++11 并发指南五(std::condition_variable 详解)
http://www.cnblogs.com/haippy/p/3252041.html 前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三 ...
- c++11 线程:让你的多线程任务更轻松
介绍 本文旨在帮助有经验的Win32程序员来了解c++ 11线程库及同步对象 和 Win32线程及同步对象之间的区别和相似之处. 在Win32中,所有的同步对象句柄(HANDLE)是全局句柄.它们 ...
- c++11 线程池学习笔记 (一) 任务队列
学习内容来自一下地址 http://www.cnblogs.com/qicosmos/p/4772486.html github https://github.com/qicosmos/cosmos ...
随机推荐
- 微信小程序热门选题
一.大体实现思路 微信小程序,现在是非常热门的,基于微信生态开发的.现在很多计算机毕业的同学,都会选择微信小程序作为毕业设计 小程序端通常都是展示数据给用户去看的,大多数情况下,这些数据不是写死的,而 ...
- 单细胞测序最好的教程(十):细胞类型注释迁移|万能的Transformer
作者按 本章节主要讲解了基于transformer的迁移注释方法TOSICA,该算法在迁移注释上达到了SOTA的水平,在注释这么卷的赛道愣是杀出了一条血路.本教程首发于单细胞最好的中文教程,未经授权许 ...
- linux部署Python UI自动化项目过程
1.安装chrome浏览器 下载 访问谷歌中文网站:Google Chrome 网络浏览器. 将页面滑到最下面,点击其他平台, 在弹出的页面选择linux 选择对应的系统版本进行下载. 下载后的deb ...
- Go 使用 Cobra 构建 CLI 程序
使用 cobra-cli 搭建手脚架 # 安装 cobra-cli go install github.com/spf13/cobra-cli@latest # 创建一个应用 mkdir myapp ...
- 1、Git简介
1.1.概述 Git 是一个开源免费的分布式版本控制系统,用于快速高效地管理各种小型或大型项目的代码. Git 不仅容易学习.占用空间小,而且性能快如闪电. Git 具有廉价的本地分支.方便的暂存区域 ...
- 【ElasticSearch】02 查询操作
准备样本: Elasticsearch 提供了基于 JSON 提供完整的查询 DSL 来定义查询 查询条件还适用于删除操作 创建索引: # PUT http://127.0.0.1:9200/st ...
- URDF(Universal Robot Description Format)—— 通用机器人描述格式URDF文件简介与生成
参考: https://zhuanlan.zhihu.com/p/477556743 详细介绍资料: https://wiki.ros.org/urdf/XML
- 对国内的人行机器人(humanoid)的一些技术类的提问?
贵公司产品在机器人仿真时具体采用的仿真软件(NVIDIA家的.开源的webot,等等)是哪款,如果没有使用NVIDIA全家桶那么其原因是什么(如:技术依赖没有独立技术.技术栈太过于复杂暂时没有精力和能 ...
- 【转载】 tensorflow batch_normalization的正确使用姿势
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/computerme/article/de ...
- 循环神经网络 —— LSTM 有状态模型(stateful LSTM)和无状态模型(stateless LSTM)
相关参考: 训练后的LSTM模型在进行预测时的初始h_n和c_n是什么或应该怎么设置? Keras中对RNN网络的statefull和stateless设置: 链接:https://keras.io/ ...