谁是std :: future的创建者?

时间:2017-12-13 16:21:01

标签: c++ multithreading c++11

Cppreferencestd::future那个

  

然后,异步操作的创建者可以使用各种方法从std :: future中查询,等待或提取值。

谁是异步操作的创建者?它是创建std::future对象的线程,还是有权访问该对象的任何线程?最后,我的问题是,非创作者是否也可以使用get上的std::future方法。

特别是,我想知道这段代码是否正确:

std::future<int> foo;
std::thread t([&foo](){ 
    foo = std::async(std::launch::async, [](){ return 4; });
});
t.join();
int n = foo.get();  // can the main thread call foo.get()?

1 个答案:

答案 0 :(得分:1)

  

谁是异步操作的创建者?它是创建std :: future对象的线程,还是有权访问该对象的任何线程?

基本上有3件事可以创造出这样的&#34;异步操作&#34;:

  • std::async
  • std::promise
  • std::packaged_task

这些&#34;创作者&#34;创建一个所谓的共享状态,其中获得的std::future平均共享访问权限。 共享状态是存储此类操作结果的位置。提供者(std::asyncstd::promisestd::packaged_task对象)和使用者(获得的std::future)访问共享状态线程安全的方式,它是一个你不应该被打扰的实现细节。

  

最后,我的问题是非创作者是否也可以在std::future上使用get方法。

原因; &#34;异步操作&#34;通常发生在不同的执行线程中,std::future的目的是安全地查询并访问此类&#34;异步操作的结果&#34;发生在其他地方,没有你明确使用任何额外的同步机制。

  

特别是,我想知道这段代码是否正确:

std::future<int> foo;
std::thread t([&foo](){ 
    foo = std::async(std::launch::async, [](){ return 4; });
});
t.join();
int n = foo.get();  // can the main thread call foo.get()?

虽然这个&#34;特别短的片段&#34;似乎没有引发竞争条件;它绝不是一个好的代码。在任何时间点,从{&#34;异步操作&#34;获得的std::future共享状态。不应该一次被多个线程使用。

在您的情况下,get()assignment operator不是线程安全的。迟早,这段代码会迅速增长,以调用竞争条件

还有一点需要注意,在代码中使用std::thread是不需要的,实际上,一个体面的实现会在启动策略时创建新线程或使用线程池std::launch::async。因此你应该这样做:

std::future<int> foo = std::async(std::launch::async, [](){ return 4; });
int n = foo.get();