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()相关推荐

  1. notify_one() 或 notify_all() 在c++中的使用要点

    notify_one() 或 notify_all() 如果在锁(mutex spin_lock)里调用,可能会导致被立刻唤醒的线程继续阻塞,因为锁被notify线程持有. c++标准上说,一些实现( ...

  2. C++ std::condition_variable::notify_one()与notify_all()

    std::condition_variable的成员函数notify_one()与notify_all()是用来唤醒阻塞在wait()的线程.假如有多个线程调用condition_variable:: ...

  3. C++11条件变量:notify_one()与notify_all()的区别

    notify_one()与notify_all()常用来唤醒阻塞的线程. notify_one():因为只唤醒等待队列中的第一个线程:不存在锁争用,所以能够立即获得锁.其余的线程不会被唤醒,需要等待再 ...

  4. c++ notify_one()和notify_all()

    c++ notify_one()和notify_all() 误区 notify_one()(随机唤醒一个等待的线程)和notify_all()(唤醒所有等待的线程),在c++里的实现原理和java不太 ...

  5. UNIX(多线程):13---condition_variable、wait、notify_one、notify_all

    条件变量std::condition_variable.wait().notify_one() 线程A: 等待一个条件满足 线程B: 专门往消息队列中放入消息(数据),达到一定条件,通知处于等待中的线 ...

  6. C++ 多线程:条件变量 std::condition_variable

    文章目录 描述 使用 描述 头文件<condition_variable> 定义 class condition_variable; 简介 之前我们也已经介绍过了C++多线程中互斥变量存在 ...

  7. 【C++】多线程与条件变量【三】

    文章目录 1 条件变量是什么? 实例1: 2 条件变量本质? 3 引入条件变量的原因? 实例2: 实例3: 实例4: 4 如何使用条件变量? 4.1 std::condition_variable 实 ...

  8. C++11中std::condition_variable的使用

    <condition_variable>是C++标准程序库中的一个头文件,定义了C++11标准中的一些用于并发编程时表示条件变量的类与方法等. 条件变量是并发程序设计中的一种控制结构.多个 ...

  9. C++条件变量使用详解

    1. condition_variable介绍 在C++11中,我们可以使用条件变量(condition_variable)实现多个线程间的同步操作:当条件不满足时,相关线程被一直阻塞,直到某种条件出 ...

最新文章

  1. 如何在 CentOS 7 中安装或升级最新的内核
  2. 第一次CM--CosH.2
  3. Leetcode1703. 得到连续 K 个 1 的最少相邻交换次数[C++题解]:难(货仓选址加强版+滑动窗口+前缀和)
  4. oracle并行查询结果不唯一,Oracle数据库并行查询出错的解决方法
  5. vue ---- 动态组件
  6. Zabbix添加nginx监控项
  7. 日志的log中如何输出变量_如何在kubernetes中优雅的输出日志
  8. 《Scala机器学习》一一1.1 Scala入门
  9. JS按字节截取字符长度实例
  10. Appium探索—Mac OS Python版
  11. 《Python极客项目编程 》——2.4 完整代码
  12. oracle rman 备份与还原
  13. python从零基础直达神经网络之基础篇 第二章 编程基础概念(二)
  14. verilog 学习笔记2 异步复位串联T触发器
  15. Linux文件-/etc/login.defs
  16. 查杀计算机病毒,计算机病毒查杀
  17. 类ChatGPT的部署与微调(上):从LLaMA、Alpaca/Vicuna/BELLE、中文版
  18. 千万年斗转星移,小屏幕见大宇宙 - “钦天明时” 天文时钟万年历应用程序(iOS App)说明
  19. 苹果三代耳机_浅谈华强北最强Airpods Pro(苹果三代蓝牙耳机)到底怎么样?
  20. C#访问局域网内共享文件夹

热门文章

  1. 猿创征文|从mysql 到kingbase(人大金仓)
  2. undefined reference to `vtkRenderingVolumeOpenGL_AutoInit_Destruct()',`vtkRenderingVolumeOpenGL_Auto
  3. 返利网PHP面试_【返利网PHP面试】面试不算难 但是公司的办事奇怪-看准网
  4. 程序员都是这样关机的
  5. js 中文汉字按拼音排序,浏览器英文环境也可正确运行
  6. Redis 入门教程(一)
  7. Cadence教程1——ncsu-cdk安装
  8. [Revit二次开发] 轴网交点创建柱子
  9. java原生的编译软件_原生态Java 程序员容易忽视的编程细节
  10. 【Linux】——库函数