• C++11 并发编程系列(三):条件变量(condition_variable)


    并发编程作为 C++11 系列的一个重大更新部分,值得我们去探究,并应用其提升程序的性能。本系列参考了其他一些文章,对 C++11 并发编程的一些要点进行了总结,并给出一些示例。

    condition_variable 类介绍

    std::condition_variable 是 C++11 多线程编程中的条件变量。

    当 std::condition_variable 对象的某个 wait 类函数被调用的时候,它使用 std::unique_lock(通过 std::mutex)来锁住当前的线程,当前的线程会一直被阻塞(进入睡眠等待状态),直到有**其他的线程在同一个 std::condition_variable 对象上调用 notify 类函数来唤醒它。

    std::condition_variable 对象通常使用 std::unique_lock<std::mutex> 来等待,如果需要使用另外的 lockable 类型,可以使用 std::condition_variable_any 类,本文后面会讲到 std::condition_variable_any 的用法。

    首先来看一个简单的例子:

    // condition_variable::notify_one
    #include <iostream>           // std::cout
    #include <thread>             // std::thread
    #include <mutex>              // std::mutex, std::unique_lock
    #include <condition_variable> // std::condition_variable
    
    std::mutex mtx;
    std::condition_variable cv;
    bool ready = false;   // 全局标志位
    
    void printId(int id)
    {
      std::unique_lock<std::mutex> lck(mtx);
      // 如果标志位不为true,则等待
      while(!ready)
      {
        // 线程被阻塞,直到标志位变为true
        cv.wait(lck);
      }
      std::cout << "thread: " << std::this_thread::get_id() << " id: " << id << "
    ";
    }
    
    void go()
    {
      std::unique_lock<std::mutex> lck(mtx);
      // 改变全局标志位
      ready = true;
      // 唤醒所有线程
      cv.notify_all();
    }
    
    int main()
    {
      std::thread threads[10];
    
      for (int i = 0; i < 10; ++i)
      {
        threads[i] = std::thread(printId, i);
      }
      std::cout << "create done.
    " ;
    
      go();
    
      for (auto &t : threads)
      {
        t.join();
      }
      std::cout << "process done.
    " ;
      return 0;
    }
    root@ubuntu:~/c++# ./cond2
    create done.
    thread: 281473284649424 id: 8
    thread: 281473343398352 id: 1
    thread: 281473335005648 id: 2
    thread: 281473326612944 id: 3
    thread: 281473318220240 id: 4
    thread: 281473309827536 id: 5
    thread: 281473301434832 id: 6
    thread: 281473293042128 id: 7
    thread: 281473276256720 id: 9
    thread: 281473351791056 id: 0
    process done.

    在上面的例子中,10 个线程被同时唤醒,因此打印的时候是乱序的。值得注意的是 while(!ready),实际上,正常情况下,cv.wait 只会被调用一次,然后等待唤醒,因为线程在调用 wait() 之后就被阻塞了。但是通过一个 while 循环来判断全局标志位是否正确,这样可以防止被误唤醒,这也是条件变量中的常见写法。

    https://murphypei.github.io/blog/2019/04/cpp-concurrent-3.html

  • 相关阅读:
    dotNet开发游戏微端
    另类Unity热更新大法:代码注入式补丁热更新
    KSFramework配置表:扩展表格解析类型
    KSFramework常见问题:Excel如何进行SVN协作、差异比较?
    KSFramework常见问题:Lua脚本热重载,内存状态数据丢失?
    KEngine:Unity3D资源的打包、加载、调试监控
    KEngine策划指南:配置表格的编辑与编译
    开发遇到的奇葩问题
    初始加载时edittext不自动获取焦点的方法
    android 监控软键盘确定 搜索 按钮并赋予点击事件
  • 原文地址:https://www.cnblogs.com/dream397/p/14649844.html
Copyright © 2020-2023  润新知