C++-----------notify_one()与notify_all()
notify_one()与notify_all()常用来唤醒阻塞的线程。
notify_one():因为只唤醒等待队列中的第一个线程;不存在锁争用,所以能够立即获得锁。其余的线程不会被唤醒,需要等待再次调用notify_one()或者notify_all()。
notify_all():会唤醒所有等待队列中阻塞的线程,存在锁争用,只有一个线程能够获得锁。那其余未获取锁的线程接着会怎么样?会阻塞?还是继续尝试获得锁?
答案是会继续尝试获得锁(类似于轮询),而不会再次阻塞。当持有锁的线程释放锁时,这些线程中的一个会获得锁。而其余的会接着尝试获得锁。
看下面的例子:
// condition_variable example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variablestd::mutex mtx;
std::condition_variable cv;
bool ready = false;void print_id(int id) {std::unique_lock<std::mutex> lck(mtx);while (!ready) cv.wait(lck);// ...std::cout << "thread " << id << '\n';
}void go() {std::unique_lock<std::mutex> lck(mtx);ready = true;cv.notify_all(); // 这是重点
}int main()
{std::thread threads[10];// spawn 10 threads:for (int i = 0; i < 10; ++i)threads[i] = std::thread(print_id, i);std::cout << "10 threads ready to race...\n";go(); // go!for (auto& th : threads) th.join();return 0;
}
运行结果为:
10 threads ready to race...
thread 2
thread 0
thread 9
thread 4
thread 6
thread 8
thread 7
thread 5
thread 3
thread 1
输出表明所有线程被唤醒,然后依旧获得了锁。
如果将go()中的cv.notify_all()改为cv.notify_one(),运行结果为:
10 threads ready to race...
thread 0
输出表明只有有一个线程被唤醒,然后该线程释放锁,这时锁已经处理非锁定状态,但是其余线程依旧处于阻塞状态。
所以,线程阻塞在condition_variable时,它是等待notify_one()或者notify_all()来唤醒,而不是等待锁可以被锁定来唤醒。
线程被唤醒后,会通过轮询方式获得锁,获得锁前也一直处理运行状态,不会被再次阻塞。
C++-----------notify_one()与notify_all()相关推荐
- notify_one() 或 notify_all() 在c++中的使用要点
notify_one() 或 notify_all() 如果在锁(mutex spin_lock)里调用,可能会导致被立刻唤醒的线程继续阻塞,因为锁被notify线程持有. c++标准上说,一些实现( ...
- C++ std::condition_variable::notify_one()与notify_all()
std::condition_variable的成员函数notify_one()与notify_all()是用来唤醒阻塞在wait()的线程.假如有多个线程调用condition_variable:: ...
- C++11条件变量:notify_one()与notify_all()的区别
notify_one()与notify_all()常用来唤醒阻塞的线程. notify_one():因为只唤醒等待队列中的第一个线程:不存在锁争用,所以能够立即获得锁.其余的线程不会被唤醒,需要等待再 ...
- c++ notify_one()和notify_all()
c++ notify_one()和notify_all() 误区 notify_one()(随机唤醒一个等待的线程)和notify_all()(唤醒所有等待的线程),在c++里的实现原理和java不太 ...
- UNIX(多线程):13---condition_variable、wait、notify_one、notify_all
条件变量std::condition_variable.wait().notify_one() 线程A: 等待一个条件满足 线程B: 专门往消息队列中放入消息(数据),达到一定条件,通知处于等待中的线 ...
- C++ 多线程:条件变量 std::condition_variable
文章目录 描述 使用 描述 头文件<condition_variable> 定义 class condition_variable; 简介 之前我们也已经介绍过了C++多线程中互斥变量存在 ...
- 【C++】多线程与条件变量【三】
文章目录 1 条件变量是什么? 实例1: 2 条件变量本质? 3 引入条件变量的原因? 实例2: 实例3: 实例4: 4 如何使用条件变量? 4.1 std::condition_variable 实 ...
- C++11中std::condition_variable的使用
<condition_variable>是C++标准程序库中的一个头文件,定义了C++11标准中的一些用于并发编程时表示条件变量的类与方法等. 条件变量是并发程序设计中的一种控制结构.多个 ...
- C++条件变量使用详解
1. condition_variable介绍 在C++11中,我们可以使用条件变量(condition_variable)实现多个线程间的同步操作:当条件不满足时,相关线程被一直阻塞,直到某种条件出 ...
最新文章
- 如何在 CentOS 7 中安装或升级最新的内核
- 第一次CM--CosH.2
- Leetcode1703. 得到连续 K 个 1 的最少相邻交换次数[C++题解]:难(货仓选址加强版+滑动窗口+前缀和)
- oracle并行查询结果不唯一,Oracle数据库并行查询出错的解决方法
- vue ---- 动态组件
- Zabbix添加nginx监控项
- 日志的log中如何输出变量_如何在kubernetes中优雅的输出日志
- 《Scala机器学习》一一1.1 Scala入门
- JS按字节截取字符长度实例
- Appium探索—Mac OS Python版
- 《Python极客项目编程 》——2.4 完整代码
- oracle rman 备份与还原
- python从零基础直达神经网络之基础篇 第二章 编程基础概念(二)
- verilog 学习笔记2 异步复位串联T触发器
- Linux文件-/etc/login.defs
- 查杀计算机病毒,计算机病毒查杀
- 类ChatGPT的部署与微调(上):从LLaMA、Alpaca/Vicuna/BELLE、中文版
- 千万年斗转星移,小屏幕见大宇宙 - “钦天明时” 天文时钟万年历应用程序(iOS App)说明
- 苹果三代耳机_浅谈华强北最强Airpods Pro(苹果三代蓝牙耳机)到底怎么样?
- C#访问局域网内共享文件夹
热门文章
- 猿创征文|从mysql 到kingbase(人大金仓)
- undefined reference to `vtkRenderingVolumeOpenGL_AutoInit_Destruct()',`vtkRenderingVolumeOpenGL_Auto
- 返利网PHP面试_【返利网PHP面试】面试不算难 但是公司的办事奇怪-看准网
- 程序员都是这样关机的
- js 中文汉字按拼音排序,浏览器英文环境也可正确运行
- Redis 入门教程(一)
- Cadence教程1——ncsu-cdk安装
- [Revit二次开发] 轴网交点创建柱子
- java原生的编译软件_原生态Java 程序员容易忽视的编程细节
- 【Linux】——库函数