谁是std :: Future的创造者

Who is the creator of a std::future?

本文关键字:创造者 Future 谁是 std      更新时间:2023-10-16

cppReference对 std::future

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

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

特别是我想知道此代码是否正确:

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对象还是可以访问该对象的任何线程的线程?

基本上有三件事可以创建这种"异步操作":

  • 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();