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()?
谁是异步操作的创建者?它是创建std :: future对象的线程,还是有权访问该对象的任何线程?
基本上有3件事可以创建这种“异步操作”:
std::async
std::promise
std::packaged_task
这些“创建者”创建了一个所谓的共享状态,其中获得的std::future
平等地共享访问权限。共享状态是存储此类操作的结果的位置。提供者(std::async
,std::promise
或std::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();