Item39 Consider void futures for one-shot event communication

原创 2017年04月30日 20:31:53

   有的时候对于一个任务来说,希望有一种机制可以和另外一个任务进行通信,尤其是那种异步运行的任务,并且会出现一种特定事件的任务,另外一个任务需要等到这个事件的发生才能继续运行,典型的,可以是等待一个重要的数据结构进行初始化,或者是等待一个计算阶段完成,又或者是检测一个重要的值。那么什么样的方式可以处理好这种线程间的通信呢?

​一个很明显的方法就是使用条件变量,一个任务就等待条件变量上,等待特定事件完成后被唤醒即可,部分代码如下:

// cv表示一个事件,m是用来保护这个条件变量
std::condition_variable cv;
std::mutex m;

// 进行事件探测和通知
.....                   // 探测事件是否发生
cv.notify_one();        // 进行事件的通知

   尽管使用条件变量可以达到我们想要的效果,但是未免有点复杂,等待事件的时候还需要使用mutex对条件变量进行保护,对于一些比较简单的事件来说没未免显得过重了。此外使用条件变量还需要考虑下面几个问题:

  1. 如果探测的任务在条件变量wait之前就进行了通知,那么等待事件的任务就会hang住
  2. 条件变量的wait会出现虚假唤醒的问题,尽管可以通过添加一个检测条件,在被虚假唤醒的时候,再次检测指定事件是否发生,但是有的时候却没有一种可行的方式用来检测。

   假设我们可以处理好上述问题,但是使用条件变量仍然会带来不少的开销,比如:在特定事件完成后必须要进行通知,接受到通知后还需要再次检查事件是否完成。这显然都是一些多余的操作。对于这个问题可以使用我们在Item38中提到的std::promisestd::future来完成,这两者构成了一个简单的channel用于通信,特定事件完成后只需要往std::promise写入一个空值来表明事件完成,那么阻塞在std::future对象上的任务就会被唤醒,部分代码如下:

std::promise<void> p;
p.set_value();  // 事件完成,进行通知

p.get_future().wait(); // 等待事件完成

   虽然std::promisestd::future这种方式显得更加简单,但是这不代表它是完美的方案,这种方式需要维护一个共享状态,需要在堆上分配存储,有分配和释放的开销,并且这种事件通知也是一次性的,而条件变量的方式可以多次触发事件。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Effective Java,Item2——Consider a builder when faced with many constructor parameters

构造函数和静态方法都有一个限制:不适合当有大量的参数时,去生成实例。 通常来说,你会采用 Telescoping constructor pattern  public class Nutrition...

《Effective_Java》 Item1:Consider static actor methods instead of constructors

使用静态工厂的优势 1.  不同于构造函数,可以赋予静态工厂更有意义的名字         eg. BigInteger的构造方法BigInteger(int, int, Random)返回一个可...
  • llsit
  • llsit
  • 2011年10月12日 23:01
  • 344

Item 1: Consider static factory methods instead of constructors

A class can provide a public static factory method to return a instance of itself.Advantage: When a ...
  • mtjwy
  • mtjwy
  • 2015年10月23日 13:54
  • 220

Item42 Consider emplacement instead of insertion

​ 如果你有一个容器,存放的是std::string类型,当你通过插入函数(如:insert、push_front、push_back或者是std::forward_list的insert_aft...

READING NOTE: FastMask: Segment Multi-scale Object Candidates in One Shot

TITLE: FastMask: Segment Multi-scale Object Candidates in One Shot

【平价数据】One Shot Learning

简介DeepMind解决小样本学习问题的文章:Matching Networks for One Shot Learning

单次自动对焦(ONE SHOT)、人工智能自动对焦(AI FOCUS)、人工智能伺服自动对焦(AI SERVO)的区别

单次自动对焦(one shot)是最为常用的。这种模式的工作过程通过半按快门来启动,在焦点未对准确前,对焦过程一直在继续。一旦处理器认为焦点准确以后,只要将快门完全按下就完成了一次拍摄过程,同时自动对...

理解 Android 的 ONE_SHOT_MAKEFILE

使用 mmm 编译的时候 Android 执行的 ONE_SHOT make, 其如何实现? mmm 的源代码在 build/envsetup.sh 中 function mmm() 64...
  • span76
  • span76
  • 2014年03月12日 17:55
  • 3266

Windows Communication Foundation入门(Part One)

前言:WCF是微软基于SOA(Service Oriented Architecture)推出的.Net平台下的框架产品,它代表了软件架构设计与开发的一种发展方向,在微软的战略计划中也占有非常重要的...
  • iamdll
  • iamdll
  • 2011年02月23日 10:55
  • 204
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Item39 Consider void futures for one-shot event communication
举报原因:
原因补充:

(最多只允许输入30个字)