繁体   English   中英

如何分配与std :: future关联的存储?

[英]How is the storage associated with std::future allocated?

获取std::future一种方法是通过std::async

int foo()
{
  return 42;
}

...

std::future<int> x = std::async(foo);

在这个例子中,如何分配x的异步状态的存储,以及哪个线程(如果涉及多个线程)负责执行分配? 此外, std::async的客户端是否可以控制分配?

对于上下文,我看到std::promise 一个构造函数可能会收到一个分配器,但是我不清楚是否可以在std::async级别自定义std::future的分配。

内存由调用std::async的线程分配,您无法控制它是如何完成的。 通常它将由new __internal_state_type的某个变体完成,但不能保证; 它可以使用malloc ,或专门为此目的选择的分配器。

从30.6.8p3 [futures.async]:

“效果:第一个函数的行为与使用launch::async | launch::deferred的策略参数调用第二个函数以及FArgs的相同参数相同。第二个函数创建与之关联的共享状态返回的未来对象......“

“第一个功能”是没有启动策略的过载,而第二个功能是启动策略的重载。

std::launch::deferred的情况下,没有其他线程,所以一切都必须在调用线程上发生。 std::launch::async的情况下,30.6.8p3继续说:

- 如果policy & launch::async非零 - 调用INVOKE (DECAY_COPY (std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...) (20.8。 2,30.3.1.2)好像在一个线程对象表示的新执行线程中,在调用async的线程中对DECAY_COPY ()的调用进行了评估。 ...

我加了重点。 由于函数和参数的副本必须在调用线程中发生,因此这基本上要求调用线程分配共享状态。

当然,您可以编写一个启动新线程的实现,等待它分配状态,然后返回引用它的future ,但为什么会这样?

仅从std::async的仅仅参数判断,似乎没有办法控制内部std::promise的分配,因此它可以只使用任何东西,尽管可能是std::allocator 虽然我认为理论上它是未指定的,但很可能共享状态是在调用线程内部分配的。 我没有在标准中找到关于此事的任何明确信息。 最终std::async是容易的异步调用一个非常专业的设备,所以你不必想如果有实际上一个std::promise的任何地方。

为了更直接地控制异步调用的行为,还有std::packaged_task ,它确实有一个allocator参数。 但仅从标准引用来看,这个分配器是否仅用于为函数分配存储(因为std::packaged_task是一种特殊的std::function )或者它是否也用于分配共享状态,这一点并不十分清楚。内部std::promise ,虽然看起来很可能:

30.6.9.1 [futures.task.members]:

效果:构造具有共享状态的新的packaged_task对象,并使用std::forward<F>(f)初始化对象的存储任务。 采用Allocator参数的构造函数使用它来分配存储内部数据结构所需的内存。

那么,它甚至不说一个std::promise下(同样为std::async ),它可能只是一个未定义的类型连接到std::future

因此,如果确实没有指定std::packaged_task如何分配其内部共享状态,那么最好的办法可能是为异步函数调用实现自己的工具。 考虑到这一点,简单地说, std::packaged_task只是一个与std::promise捆绑在一起的std::functionstd::async只是在一个新线程中启动一个std::packaged_task (好吧,除非它没有),这不应该是一个太大的问题。

但实际上这可能是规范中的疏忽。 虽然分配控制并不真正适合std::async ,但std::packaged_task的解释及其对分配器的使用可能会更清楚一些。 但这也可能是故意的,所以std::packaged_task可以随意使用它甚至不需要内部的std::promise

编辑:再次阅读,我认为上面的标准引用确实说, std::packaged_task的共享状态使用提供的分配器分配的,因为它是“内部数据结构”的一部分 ,无论那些是什么(没有但是,我需要成为一个真正的std::promise 所以我认为std::packaged_task应该足以明确控制异步任务的std::future的共享状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM