• c++多线程基础4(条件变量)


    条件变量是允许多个线程相互交流的同步原语。它允许一定量的线程等待(可以定时)另一线程的提醒,然后再继续。条件变量始终关联到一个互斥

    定义于头文件 <condition_variable>

    condition_variable:

    condition_variable 类是同步原语,能用于阻塞一个线程,或同时阻塞多个线程,直至另一线程修改共享变量(条件)并通知 condition_variable 。

    有意修改变量的线程必须

    1. 获得 std::mutex (典型地通过 std::lock_guard )
    2. 在保有锁时进行修改
    3. 在 std::condition_variable 上执行 notify_one 或 notify_all (不需要为通知保有锁)

    即使共享变量是原子的,也必须在互斥下修改它,以正确地发布修改到等待的线程。

    任何有意在 std::condition_variable 上等待的线程必须

    1. 获得 std::unique_lock<std::mutex> ,在与用于保护共享变量者相同的互斥上
    2. 执行 wait 、 wait_for 或 wait_until ,等待操作自动释放互斥,并悬挂线程的执行
    3. condition_variable 被通知时,时限消失或虚假唤醒发生,线程被唤醒,且自动重获得互斥。之后线程应检查条件,若唤醒是虚假的,则继续等待

    代码:

     1 #include <iostream>
     2 #include <thread>
     3 #include <mutex>
     4 #include <condition_variable>
     5 using namespace std;
     6 
     7 std::mutex m;
     8 std::condition_variable cv;
     9 string data;
    10 bool ready = false;
    11 bool processed = false;
    12 
    13 void worker_thread() {
    14     //等待直至 main() 发送数据
    15     std::unique_lock<std::mutex> lk(m);//拥有mutex,并调用mutex.lock()对其上锁
    16     cv.wait(lk, []{return ready;});//等价于 while(!ready) cv.wait(lk);
    17     //在调用 wait 时会自动执行 lk.unlock()
    18     //当 wait 被其它线程唤醒时,锁会自动恢复 wait 之前的状态
    19 
    20     //等待后,我们占有锁
    21     cout << "worker thread is processing data
    ";
    22     data += " after processing";
    23 
    24     //发送数据回 main
    25     processed = true;
    26     cout << "worker thread sigals data processing completed
    ";
    27 
    28     lk.unlock();//通知前手动解锁,以避免等待线程再阻塞
    29     cv.notify_one();
    30 }
    31 
    32 int main(void) {
    33     std::thread worker(worker_thread);
    34 
    35     data = "Example data";
    36     //发送数据到worker线程
    37     {
    38         std::lock_guard<std::mutex> lk(m);
    39         ready = true;
    40         cout << "main() sigals data ready for processing
    ";
    41     }
    42     cv.notify_one();
    43 
    44     //等候worker
    45     {
    46         std::unique_lock<std::mutex> lk(m);
    47         cv.wait(lk, []{return processed;});//等价于while(!processed) cv.wait(lk)
    48     }
    49     cout << "Back in main(), data = " << data << '
    ';
    50 
    51     worker.join();
    52 
    53 // 输出:
    54 // main() sigals data ready for processing
    55 // worker thread is processing data
    56 // worker thread sigals data processing completed
    57 // Back in main(), data = Example data after processing
    58 
    59     return 0;
    60 }
    View Code

    注意:虚假唤醒问题 https://segmentfault.com/q/1010000010421523/a-1020000010457503

    https://blog.csdn.net/shizheng163/article/details/83661861

    condition_variable_any 类是 std::condition_variable 的泛化。相对于只在 std::unique_lock<std::mutex> 上工作的 std::condition_variable , condition_variable_any 能在任何满足基础可锁 (BasicLockable) 要求的锁上工作,操作和 std::condition_variable 完全相同

  • 相关阅读:
    HTML5 & CSS3编程入门经典 ((美)Rob Larsen) pdf扫描版
    HTML5+JavaScript动画基础 完整版 中文pdf扫描版
    HTML5程序开发范例宝典 完整版 (韩旭等著) 中文pdf扫描版
    HTML5从入门到精通(明日科技) 中文pdf扫描版
    HTML5秘籍(第2版) 中文pdf扫描版
    HTML5与CSS3实例教程(第2版) 附源码 中文pdf扫描版
    windows下一分钟配置ngnix实现HLS m3u8点播
    linux下搭建生成HLS所需的.ts和.m3u8文件
    使用Flash Media Server(FMS)录制mp4格式的视频
    FMS 客户端带宽计算、带宽限制
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/8544543.html
Copyright © 2020-2023  润新知