谁是std :: future的创造者?

问题描述 投票:3回答:1

Cppreference说关于std::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()?
c++ multithreading c++11
1个回答
1
投票

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

基本上有3件事可以创建这种“异步操作”:

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

这些“创建者”创建了一个所谓的共享状态,其中获得的std::future平等地共享访问权限。共享状态是存储此类操作的结果的位置。提供者(std::asyncstd::promisestd::packaged_task对象)和使用者(获得的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()?

虽然这个“特别短的片段”似乎没有引起竞争条件;它绝不是一个好的代码。在任何时间点,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();
© www.soinside.com 2019 - 2024. All rights reserved.