《C++并发编程实战》读书笔记(3):并发操作的同步

打印 上一主题 下一主题

主题 941|帖子 941|积分 2823

1、条件变量

当线程需要等待特定事件发生、或是某个条件成立时,可以使用条件变量std::condition_variable,它在标准库头文件内声明。
  1. std::mutex mut;
  2. std::queue<data_chunk> data_queue;
  3. std::condition_variable data_cond;
  4. void data_preparation_thread()
  5. {
  6.     while (more_data_to_prepare())
  7.     {
  8.         const data_chunk data = prepare_data();
  9.         std::lock_guard<std::mutex> lk(mut);
  10.         data_queue.push(data);
  11.         data_cond.notify_one();
  12.     }
  13. }
  14. void data_processing_thread()
  15. {
  16.     while (true)
  17.     {
  18.         std::unique_lock<std::mutex> lk(mut);
  19.         data_cond.wait(lk, [] { return !data_queue.empty(); });
  20.         data_chunk data = data_queue.front();
  21.         data_queue.pop();
  22.         lk.unlock();
  23.         process(data);
  24.         if (is_last_chunk(data)) { break; }
  25.     }
  26. }
复制代码
wait()会先在内部调用lambda函数判断条件是否成立,若条件成立则wait()返回,否则解锁互斥并让当前线程进入等待状态。当其它线程调用notify_one()时,当前调用wait()的线程被唤醒,重新获取互斥锁并查验条件,若条件成立则wait()返回(互斥仍被锁住),否则解锁互斥并继续等待。
wait()函数的第二个参数可以传入lambda函数,也可以传入普通函数或可调用对象,也可以不传。
notify_one()唤醒正在等待当前条件的线程中的一个,如果没有线程在等待,则函数不执行任何操作,如果正在等待的线程多于一个,则唤醒的线程是不确定的。notify_all()唤醒正在等待当前条件的所有线程,如果没有正在等待的线程,则函数不执行任何操作。
2、使用future等待一次性事件发生

C++标准程序库有两种future,分别由两个类模板实现,即std::future和std::shared_future,它们的声明位于头文件内。
2.1、从后台任务返回值

由于std::thread没有提供直接回传结果的方法,所以我们使用函数模板std::async()来解决这个问题。std::async()以异步方式启动任务,并返回一个std::future对象,运行函数一旦完成,其返回值就由该对象持有。在std::future对象上调用get()方法时,当前线程就会阻塞,直到std::future准备妥当并返回异步线程的结果。std::future模拟了对异步结果的独占行为,get()仅能被有效调用一次,调用时会对目标值进行移动操作。
[code]int find_the_answer_to_ltuae();void do_other_stuff();int main(){    std::future the_answer = std::async(find_the_answer_to_ltuae);    do_other_stuff();    std::cout
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

自由的羽毛

金牌会员
这个人很懒什么都没写!

标签云

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