c++11 线程间同步---利用std::condition_variable实现
1.前言
很多时候,我们在写程序的时候,多多少少会遇到下面种需求

一个产品的大致部分流程,由工厂生产,然后放入仓库,最后由销售员提单卖出去这样。
在实际中,仓库的容量的有限的,也就是说,工厂不能一直生产产品,如果生产太多就会导致仓库满了没地方存放。
为了达到生产效率最大化,就会这样做,只要仓库空了一点位置,工厂就开始生产,等仓库满了以后,工厂就停止生产。
在这过程中,工厂生产产品的速度是销售部卖出产品的速度快很多的。
回到编程中,工厂就是一个单独子线程, 销售部也是一个单独子线程
要想模拟达到上边想要的需求,这就需要用线程间同步啦。
情形1

情形2

情形3

2.准备工作
| 演示环境 | 解决方式 |
|---|---|
| vs2017 | c++11 条件变量 |
线程间同步机制,有很多的实现方式,这里采用了条件变量的方式。
c++11 把线程thread添加到了标准库,我们可以很方便的使用多线程和进行移植。
只需要引入thread头文件即可使用。
#include <thread>
此次我们需要用到的头文件
#include <iostream>
#include <atomic>
#include <thread> /*线程类*/
#include <condition_variable> /*条件变量*/
#include <mutex> /*线程锁*/
前提: 在使用 std::condition_variable 时,需要配合 mutex 来使用std::unique_lock进行上锁/解锁。
3.代码演示
#include <iostream>
#include <thread>
#include <atomic>
#include <condition_variable>
#include <mutex>
std::mutex _mutex; /*线程锁*/
std::condition_variable cv; /*条件变量*/
std::atomic_int productCnt = 0; /*公共变量,产品库存数量*/
std::atomic_bool isReady = false; /*公共变量,防止假性唤醒线程*/
/*生产产品*/
void Fun1()
{
while (true)
{
std::unique_lock<std::mutex> lock(_mutex);
std::cout << "+++生产了产品, 库存剩余:" << ++productCnt << std::endl;
isReady = true; /*产品生产好了*/
cv.notify_all(); /*唤醒线程,通知Fun2()产品可以卖了*/
cv.wait(lock); /*睡眠线程,Fun1()在等待Fun2()把产品卖出去再生产*/
}
}
/*销售产品*/
void Fun2()
{
while (true)
{
std::unique_lock<std::mutex> lock(_mutex);
/*Fun1()产品还没生产好,Fun2()在这睡大觉*/
if (!isReady) {
cv.wait(lock);
}
std::cout << "---卖出了产品, 库存剩余:" << --productCnt << std::endl;
isReady = false;/*Fun2()把产品买出去啦*/
cv.notify_all();/*Fun2()告诉Fun1()产品已经卖了,可以继续生产了*/
}
}
/*主函数*/
int main(int argc, char **argv)
{
std::thread t1(Fun1);/*声明线程1*/
std::thread t2(Fun2);/*声明线程2*/
t1.join();/*开启线程1*/
t2.join();/*开启线程2*/
return 0;
}
调试结果

c++11 线程间同步---利用std::condition_variable实现的更多相关文章
- C++11并发——多线程条件变量std::condition_variable(四)
https://www.jianshu.com/p/a31d4fb5594f https://blog.csdn.net/y396397735/article/details/81272752 htt ...
- conditon_variable(条件变量)用于线程间同步
conditon_variable(条件变量)用于线程间同步 condition_variable有5个函数,函数名及对应的功能如下: wait阻塞自己,等待唤醒 wait_for阻塞自己,等待唤醒, ...
- C#线程间同步无法关闭
用C#做了个线程间同步的小程序,但每次关闭窗口后进程仍然在,是什么原因? 解决方法: 要加一句 线程.IsBackground = true; 否则退出的只是窗体 上面的方法没看懂... MSDN上说 ...
- Linux系统编程(29)——线程间同步(续篇)
线程间的同步还有这样一种情况:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行.在pthread库中通过条件变 ...
- linux线程间同步方式汇总
抽空做了下linux所有线程间同步方式的汇总(原生的),包含以下几个: 1, mutex 2, condition variable 3, reader-writer lock 4, spin loc ...
- rtt学习之线程间同步与通信
一 线程间的同步与互斥:信号量.互斥量.实践集 线程互斥是指对于临界区资源访问的排它性,如多个线程对共享内存资源的访问,生产消费型对产品的操作.临界区操作操作方法有: rt_hw_interrupt_ ...
- Linux进程间通信与线程间同步详解(全面详细)
引用:http://community.csdn.net/Expert/TopicView3.asp?id=4374496linux下进程间通信的几种主要手段简介: 1. 管道(Pipe)及有名管道( ...
- C++ 11 线程的同步与互斥
这次写的线程的同步与互斥,不依赖于任何系统,完全使用了C++11标准的新特性来写的,就连线程函数都用了C++11标准的lambda表达式. /* * thread_test.cpp * * Copyr ...
- 线程间同步之 semaphore(信号量)
原文地址:http://www.cnblogs.com/yuqilin/archive/2011/10/16/2214429.html semaphore 可用于进程间同步也可用于同一个进程间的线程同 ...
随机推荐
- 在 Linux 中,最直观、最可见的部分就是 文件系统(file system)
在 Linux 中,最直观.最可见的部分就是 文件系统(file system).下面我们就来一起探讨一下关于 Linux 中国的文件系统,系统调用以及文件系统实现背后的原理和思想.这些思想中有一些来 ...
- Ubuntu 软件更新 系统升级
注意:操作前请先切换root权限 sudo su 1.软件更新 更新源 apt-get update 更新软件 apt-get upgrade 2.系统升级 安装系统更新 apt-get dist-u ...
- k8s创建资源的两种方式及DaemonSet应用(5)
一.创建方式分类 Kubernetes 支持两种方式创建资源: (1)用 kubectl 命令直接创建,比如: kubectl run httpd-app --image=reg.yunwei.com ...
- mysql基础之视图、事务、索引、外键
一.视图 视图是一个虚拟表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据.但是,视图并不在数据库中以存储的数据值集形式存在.行和列数据来自由定义视图的查询所引用的表,并且在引用 ...
- 6.2 gzip:压缩或解压文件
gzip命令 用于将一个大的文件通过压缩算法(Lempel-Ziv coding(LZ77))变成一个小的文件.gzip命令不能直接压缩目录,因此目录需要先用tar打包成一个文件,然后tar再调用gz ...
- C语言volatile
原文地址: http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html volatile提醒编译器它后面所定义的变量随时都有 ...
- HDFS的小文件问题
HDFS 中任何一个文件,目录或者数据块在 NameNode 节点内存中均以一个对象形式表示(元数据),而这受到 NameNode 物理内存容量的限制.每个元数据对象约占 150 byte,所以如果有 ...
- 『言善信』Fiddler工具 — 2、HTTP请求内容详解
目录 1.HTTP协议介绍 2.使用Fiddler抓取一个请求 3.НТТP请求报文 (1)НТТP请求报文说明 (2)请求行 (3)请求头(Request Header) (4)请求体 4.НТТР ...
- 痞子衡嵌入式:关于i.MXRT中FlexSPI外设lookupTable里配置Normal read的一个小误区
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT中FlexSPI外设lookupTable里配置Normal read的一个小误区. 关于串行四线NOR Flash,当其作 ...
- [LeetCode] 1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?
都儿童节了,为什么要折磨一个几百个月大的孩子? 把题意读懂挺难的.不过读懂后基本也就知道怎么做了.恶心的是int类型可能会越界,要用long类型(很难想到).这题不好 [1744. 你能在你最喜欢的那 ...