承诺/未来的好处与参考回报相比



我是线程概念的新手C++并且正在尝试理解承诺/未来抽象的好处。有了承诺和未来,我知道它允许异步函数像常规子例程一样"返回"。但是,我不清楚除了使用引用的参数来做同样的事情之外,它还提供了什么。

#include <iostream>
#include <thread>
void f(int& x)
{
x += 1;
}
int main()
{
int a = 1;
std::thread t(f, std::ref(a));
t.join();
std::cout << a << 'n';
}

在上面的例子中,我使函数f()通过传递引用来"返回"整数。这是安全的,因为我只在线程连接后获取值。现在,使用承诺/未来有什么好处是上述范式无法做到的吗?

这是安全的,因为我只在线程连接后获取值

嗯,这就是重点,不是吗?如果某些代码变得"不安全"所需要的只是某人在错误的时间无意中使用变量,这真的"安全"吗?如果"安全"和"完全破坏"的区别是两行的顺序变化,没有编译器能抓住问题,那真的是"安全"吗?

如果调用异步操作,则执行此操作的主要原因是要在该操作进行时执行其他操作。因此,离开当前的堆栈帧是重点。大多数代码看起来都不像您的简单示例。

你的例子只是"安全"的,因为它太简单了。引入任何复杂性,它变得越来越不安全。

线程是否引发了异常而不是返回有效值?您是否确保被引用对象的生存期一直持续到线程完成对其的写入?如果您希望线程能够完成任务并执行不同的任务(而不是每次想要执行异步过程时都产生创建新std::thread的成本),当值准备好时,您如何与外界进行通信?

promise/future对所有这些问题都有答案。它有一个显式机制,用于跨线程引导异常。牧羊人的寿命受到严格控制,因此根本无法断裂。每个promise/future都是独立的,因此一个线程可以有很多个,任何future都可以知道promised值何时准备就绪。等。

总之,promise/future大规模安全的工具。引入的复杂性越多,您的安全性就越低。

最新更新