一生一世学坛

 找回密码
 立即注册
搜索
查看: 6783|回复: 1
打印 上一主题 下一主题

锁和条件变量的配合使用(C++)

[复制链接]

334

主题

385

帖子

6830

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
6830
跳转到指定楼层
楼主
发表于 2020-9-7 20:10:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include <iostream>
  2. #include <thread>
  3. #include <functional>
  4. #include <mutex>
  5. #include <condition_variable>
  6. using namespace std::placeholders;
  7. class Application
  8. {
  9.     std::mutex m_mutex;
  10.     std::condition_variable m_condVar;
  11.     bool m_bDataLoaded;
  12. public:
  13.     Application()
  14.     {
  15.         m_bDataLoaded = false;
  16.     }
  17.     void loadData()
  18.     {
  19.         std::cout<<"loadData start"<<std::endl;
  20.         // Make This Thread sleep for 1 Second
  21.         std::this_thread::sleep_for(std::chrono::milliseconds(1000));
  22.         std::cout<<"Loading Data from XML"<<std::endl;
  23.         // Lock The Data structure
  24.         std::lock_guard<std::mutex> guard(m_mutex);
  25.         // Set the flag to true, means data is loaded
  26.         m_bDataLoaded = true;
  27.         // Notify the condition variable
  28.         m_condVar.notify_one();//通知另一个线程去检查m_bDataLoaded是否为真
  29.   }
  30.     bool isDataLoaded()
  31.     {
  32.         if (m_bDataLoaded) {
  33.             std::cout << "load true" << std::endl;
  34.         } else {
  35.             std::cout << "load false" << std::endl;
  36.         }
  37.     return m_bDataLoaded;
  38.   }
  39.     void mainTask()
  40.     {
  41.         std::cout<<"Do Some Handshaking"<<std::endl;
  42.         // Acquire the lock
  43.         std::unique_lock<std::mutex> mlock(m_mutex);
  44.         // Start waiting for the Condition Variable to get signaled
  45.         // Wait() will internally release the lock and make the thread to block
  46.         // As soon as condition variable get signaled, resume the thread and
  47.         // again acquire the lock. Then check if condition is met or not
  48.         // If condition is met then continue else again go in wait.
  49.         m_condVar.wait(mlock, std::bind(&Application::isDataLoaded, this));//检查m_bDataLoaded是否为真,为真则线程向下执行,为假则阻塞线程并暂时释放锁(释放锁其它线程才可以顺利使用资源)

  50.         std::cout<<"Do Processing On loaded Data"<<std::endl;
  51.     }
  52. };
  53. int main()
  54. {
  55.     Application app;
  56.     std::thread thread_1(&Application::mainTask, &app);
  57.     std::thread thread_2(&Application::loadData, &app);
  58.     thread_1.join();
  59.     thread_2.join();

  60.     return 0;
  61. }

  62. /*输出结果
  63. Do Some Handshaking
  64. load false
  65. loadData start
  66. Loading Data from XML
  67. load true
  68. Do Processing On loaded Data
  69. */
复制代码


回复

使用道具 举报

334

主题

385

帖子

6830

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
6830
沙发
 楼主| 发表于 2021-1-29 14:32:06 | 只看该作者
条件变量的使用:
#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 do_print_id(int id)

{

    std::unique_lock <std::mutex> lck(mtx);

    while (!ready) // 如果标志位不为 true, 则等待...

        cv.wait(lck); // 当前线程被阻塞,直到notify被调用,在阻塞的过程中lck是被解开的

    // 线程被唤醒, 且ready,继续往下执行打印线程编号id.

    std::cout << "thread " << id << '\n';

}



void go()

{

    std::unique_lock <std::mutex> lck(mtx);

    ready = true; // 设置全局标志位为 true.

    cv.notify_all(); // 唤醒所有线程.

}



int main()

{

    std::thread threads[10];

    // spawn 10 threads:

    for (int i = 0; i < 10; ++i)

        threads[i] = std::thread(do_print_id, i);



    std::cout << "10 threads ready to race...\n";

    go(); // go!



  for (auto & th:threads)

        th.join();



    return 0;

}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|分享学习  

GMT+8, 2024-5-17 10:56 , Processed in 0.069928 second(s), 6 queries , File On.

声明:本站严禁任何人以任何形式发表违法言论!

本站内容由网友原创或转载,如果侵犯了您的合法权益,请及时联系处理!© 2017 zamxqun@163.com

皖公网安备 34010402700634号

皖ICP备17017002号-1

快速回复 返回顶部 返回列表