我创建一个
std::packaged_task
,将其推送到 std::list
并将其 std::future
返回给用户,如下所示:
future_t emplace(...)
{
//...
auto task = std::make_shared<std::packaged_task<return_t()>>(
std::bind(std::forward<F>(f), std::forward<Args>(args)...));
tasks.emplace_back(task);
std::future<return_t> result = task->get_future();
//...
return result;
}
在另一个线程中,我们可以随时清除任务列表:
// another thread
std::list<task_t> temp_{};
tasks.swap(temp_);
但是用户仍然可以调用 std::future:
auto result = emplace(...);
// do something and the tasks list has been clear in anthor thread
auto ret = result.get();
收到异常错误,因为 std::promise 已被破坏:
C++ exception with description "std::future_error: Broken promise" thrown in the test body.
我可以使用异常表达式来避免程序崩溃:
try
{
auto ret = result.get();
}
catch (...)
{
}
我可以在没有异常表达的情况下避免
std::future_error
吗?
我的问题是:还有其他方法来检测 std::promise 是否存在吗?
恐怕没有直接的方法来检测承诺是否仍然存在。如果必须这样做,您可能需要做一些额外的工作来保持
task
(或相应的 future
)的状态,这比当前的解决方案更复杂。默认情况下,所有 future
均无效。每当您执行任务时,您都会将 future
标记为 valid。每当您要通过 future
获得结果时,请检查它是否有效。
注意:您必须处理此状态的同步,因为此状态在不同线程之间共享。这听起来很复杂,对吗?您将在成对的承诺和未来之外分享另一个数据。我不建议也不认为有必要这样做。 当您使用
std::promise
和
std::future
时,所有异常都应在 std::future::get
中处理。