当前位置: 首页 > 知识库问答 >
问题:

为什么我们需要d::promise和d::f实现?

黎浩然
2023-03-14

我想知道为什么我们需要std::promise和std::future?为什么c 11标准将get和set_ value分为两个独立的类std::future和std::promise?在这篇文章的回答中,它提到:

它被分成这两个独立的“接口”的原因是为了对“消费者/阅读器”隐藏“写入/设置”功能。

我不明白躲在这里的好处。但是,如果我们只有一个类的“未来”,那不是更简单吗?例如:promise.set_value可以用future.set_value代替。

共有2个答案

燕智
2023-03-14

我将Promise/Future视为异步队列(仅用于保存单个值)。

未来是队列的读取端。promise是队列的写入端。

这两者的用法通常是不同的:生产者通常只是向“队列”写入,而消费者只是从中读取。正如您所提到的,虽然生产者可以读取值,但很少有理由这样做,因此优化特定的操作很少被视为优先事项。

在通常的情况下,生产者产生价值,并将其放入promise中。消费者从未来获得价值。每个“客户机”都使用一个专门用于一个简单任务的简单接口,因此更容易设计和记录代码,并确保(例如)消费者代码不会干扰与产生价值相关的内容(反之亦然)。是的,这样做是可能的,但额外的工作足够多,不太可能发生意外。

翟誉
2023-03-14

promise/future要解决的问题是将值从一个线程引导到另一个线程。它也可以传输异常。

因此,源线程必须有一些可以与之对话的对象,以便将所需的值发送给另一个线程。好吧…谁拥有那个东西?如果源有一个指向目标线程拥有的某个对象的指针,那么源如何知道目标线程是否删除了该对象?也许目标线程不再关心该值;也许有些事情改变了,以至于它决定把你的线掉在地板上,然后忘掉它。

在某些情况下,这是完全合法的代码。

所以现在的问题变成了为什么源不拥有Promise,而只是给目标一个指向它的指针/引用?嗯,这有一个很好的理由:Promise归源线程所有。一旦源线程终止,Promise将被销毁。因此给目标线程留下对已销毁的Promise的引用。

哎呀。

因此,唯一可行的解决方案是拥有两个成熟的对象:一个用于源,一个用于目的地。这些对象共享被传输的值的所有权。当然,这并不意味着他们不能是同一类型;您可以使用类似于< code>shared_ptr的代码

然而,考虑一下当前promise/未来的界面。

promise是不可复制的。您可以移动它,但不能复制它。future也是不可复制的,但未来可以成为可复制shared_future。因此,您可以有多个目标,但只有一个源。

promise只能设置值;它甚至不能把它拿回来future只能获取值;它无法设置它。因此,您有一个非对称接口,它完全适合这个用例。您不希望目标能够设置值,而源能够检索值。这是向后的代码逻辑。

这就是你想要两个物体的原因。你有一个非对称接口,最好用两个相关但独立的类型和对象来处理。

 类似资料:
  • 我非常熟悉C 11的、和组件(例如,请参见此答案),它们都是直截了当的。 然而,我不能完全理解什么是d::promise,它做了什么,以及在哪些情况下最好使用它。标准文档本身不包含超出类概要的大量信息,std::线程也是如此。 有人能给我举一个简短的例子,说明在什么情况下需要,它是最惯用的解决方案吗?

  • 问题内容: 我正在学习Go,并且一直沉迷于Go旅游(exercise- stringer.go:https : //tour.golang.org/methods/7)。 这是一些代码: 所以我想出了is 的内部表示,所以散布算子起作用了。但我得到: 有没有搞错?字符串切片也不起作用,这是怎么回事? 编辑 :对不起,我的问题中有一个错误- 错误是关于type的,不是。我在玩代码,并且粘贴了错误的输

  • 问题内容: Angular应用使用属性而不是事件。 为什么是这样? 问题答案: ng-click包含一个角度表达式。Angular表达式是在Angular 范围的上下文中求值的,该范围绑定到具有ng- click属性的元素或该元素的祖先。 Angular表达式语言不包含流控制语句,也不能声明变量或定义函数。这些限制意味着模板只能访问由控制器或指令提供的变量和运行功能。

  • 以我的拙见,关于“什么是单子”这个著名问题的答案,尤其是投票最多的答案,试图解释什么是单子,而没有明确解释为什么单子是真正必要的。它们能被解释为一个问题的解决方案吗?

  • 为什么我们需要字典? 计算机最适合使用数字,而人类最适合使用姓名。我们创建了DNS以便记住主机名而不是IP地址。字典以相同的方式使用,因此我们可以记住AVP名称而不是类型编号。当FreeRADIUS解析请求或生成响应时,会查阅字典。 但是,字典与DNS不同,因为RADIUS客户端不知道FreeRADIUS使用的这些“友好”名称。永远不会在RADIUS客户端和RADIUS服务器之间交换AVP名称。

  • 问题内容: 我一直在研究,发现从2.1开始就可以使用实体图。 但是我还不了解实体图的优点。 我知道使用实体图的优点之一是我们只能在整个实体中指定要获取的数据,但是如果我们要整个实体,还有其他理由使用实体图吗?还是仅在要检索部分数据时才应使用实体图? 当我们使用实体图时,它还有其他目的或优点,我想知道。 问题答案: 在Jpa中,休眠与关联关系一直是性能的问题。 一次又一次地在事务中延迟加载关联会导致