Jar*_*ock 12 c++ asynchronous future c++-standard-library c++11
获得的一种方法std::future是通过std::async:
int foo()
{
return 42;
}
...
std::future<int> x = std::async(foo);
Run Code Online (Sandbox Code Playgroud)
在这个例子中,如何x分配异步状态的存储,以及哪个线程(如果涉及多个线程)负责执行分配?此外,客户std::async是否可以控制分配?
对于情况下,我看到一个构造函数中std::promise可能会收到一个分配器,但如果它是可以自定义的配置,目前还不清楚我std::future的水平std::async.
内存由调用的线程分配std::async,您无法控制它是如何完成的.通常它会通过某种变体来完成new __internal_state_type,但不能保证; 它可以使用malloc,或专门为此目的选择的分配器.
从30.6.8p3 [futures.async]:
"效果:第一个函数的行为一样与政策争论的第二个函数的调用
launch::async | launch::deferred和相同的参数F和Args.第二个函数创建一个与返回的未来对象相关联的共享状态......"
"第一个功能"是没有启动策略的过载,而第二个功能是启动策略的重载.
在这种情况下std::launch::deferred,没有其他线程,所以一切都必须在调用线程上发生.在std::launch::async30.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),就像在由线程对象表示的新执行线程中一样,在调用DECAY_COPY ()的线程中调用被调用async....
我加了重点.由于函数和参数的副本必须在调用线程中发生,因此这基本上要求调用线程分配共享状态.
当然,您可以编写一个启动新线程的实现,等待它分配状态,然后返回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分配其内部共享状态,那么最好的办法可能是为异步函数调用实现自己的工具.考虑到这一点,简单地说,a std::packaged_task只是std::function捆绑了a std::promise,std::async只是std::packaged_task在一个新线程中开始(好吧,除非它没有),这不应该是一个太大的问题.
但实际上这可能是规范中的疏忽.虽然分配控制并不真正适合std::async,但std::packaged_task分配器的解释和使用可能会更清楚一些.但这也可能是故意的,因此std::packaged_task可以随意使用它想要的东西,甚至不需要std::promise内部.
编辑:再读一遍,我认为上面的标准引用确实说,std::packaged_task共享状态是使用提供的分配器分配的,因为它是"内部数据结构"的一部分,无论那些是什么(不需要std::promise虽然是实际的.所以我认为std::packaged_task应该足以明确控制异步任务的共享状态std::future.