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

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

Android6.0 VSync信号如何到用户进程

在http://blog.csdn.net/kc58236582/article/details/52763534博客的VSync信号的分发过程那节中我们已经详细分析了VSync信号的分发过程,其中E...
  • kc58236582
  • kc58236582
  • 2016年10月22日 15:36
  • 1861

spring5.0 之@Primary注解的应用

spring5.0 之@Primary注解的应用 在spring容器中,如果同一个类型有多个实例,但我们需要注入一个的时候,我们必须采取措施,不然spring容器 会报错:....required a...
  • doctor_who2004
  • doctor_who2004
  • 2017年07月18日 21:50
  • 4836

【Flume】flume中transactionCapacity和batchSize概念的具体分析和解惑

不知道各位用过flume的读者对这两个概念是否熟悉了解 一开始本人的确有点迷惑,觉得这是不是重复了啊? 没感觉到transactionCapacity的作用啊? batchSize又是干啥的啊?...
  • chiweitree
  • chiweitree
  • 2015年03月12日 15:47
  • 3129

Exploiting Event-Based Communication for Real-Time Distributed and Parallel Video Content Analysis

  • 2007年07月04日 11:08
  • 2.1MB
  • 下载

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

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

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

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

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
  • 246

Item42 Consider emplacement instead of insertion

​ 如果你有一个容器,存放的是std::string类型,当你通过插入函数(如:insert、push_front、push_back或者是std::forward_list的insert_aft...
  • zhangyifei216
  • zhangyifei216
  • 2017年06月05日 14:27
  • 528

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

TITLE: FastMask: Segment Multi-scale Object Candidates in One Shot
  • joshua_1988
  • joshua_1988
  • 2017年04月18日 21:11
  • 369

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

单次自动对焦(one shot)是最为常用的。这种模式的工作过程通过半按快门来启动,在焦点未对准确前,对焦过程一直在继续。一旦处理器认为焦点准确以后,只要将快门完全按下就完成了一次拍摄过程,同时自动对...
  • l106439814
  • l106439814
  • 2011年09月20日 18:43
  • 21250
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Item39 Consider void futures for one-shot event communication
举报原因:
原因补充:

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