Допустим, у нас есть следующий код:
#include <iostream>
#include <future>
int main() {
auto packagedTask = std::packaged_task<int()>([] {
std::cout << "hello!\n";
return 10;
});
auto packagedTaskFuture = packagedTask.get_future();
auto packagedTaskPtr = std::make_shared<decltype(packagedTask)>(std::move(packagedTask));
auto v1 = packagedTaskFuture.valid(); // is valid
auto v2 = packagedTaskFuture.wait_for(std::chrono::seconds(0)); // timeout state
(*packagedTaskPtr)(); // execute task
auto v3 = packagedTaskFuture.wait_for(std::chrono::seconds(1)); // ready state
auto v4 = packagedTaskFuture.get(); // 10
return 0;
}
Он отлично работает в моей среде Visual Studio, как вы видите, я получаю std::future
непосредственно перед тем, как переместить std::packaged_task
во вновь созданный std::shared_ptr
.Я ознакомился со стандартом C ++ в отношении std::packaged_task
, поэтому §30.6.9.1 packaged_task(packaged_task&& rhs) noexcept
p.6:
Эффекты: создает новый объект packaged_task и передает владение общим состоянием rhs в* это, оставляя rhs без общего состояния.Перемещает сохраненную задачу из rhs в * this.
и §30.6.9 p.2 говорит:
Когда вызывается объект packaged_task, вызывается его сохраненная задачаи результат (будь то нормальный или исключительный) сохраняется в общем состоянии.Любые фьючерсы, которые совместно используют общее состояние, смогут получить доступ к сохраненному результату.
На основании этой информации у меня есть два вопроса:
1) Правильно ли я говорю, что std::packaged_task
будет связан с тем же std::future
после std::move
?
2) Безопасно ли использовать мой std::shared_ptr
в другом потоке и выполнять там задачу, проверяя std::future
из текущего?