C++ 20 并发编程 std::promise
std::promise
和std::future
是一对, 通过它们可以进行更加灵活的任务控制
promise
通过函数set_value()
传入一个值, 异常, 或者通知, 并异步的获取结果
例子:
void product(std::promise<int>&& intPromise, int a, int b)
{intPromise.set_value(a * b);
}int main(int argc, char* argv[])
{int a = 666;int b = 999;std::promise<int> productPromise;std::future<int> productResult = productPromise.get_future();std::jthread productThread(product, std::move(productPromise), a, b);std::cout << std::format("product is {}\n", productResult.get());
}
std::future:
- 从
promise
获取值 - 询问值是否可用
- 等待通知
- 创建
shared_future
成员函数
(构造函数) | 构造 future 对象 (公开成员函数) |
---|---|
(析构函数) | 析构 future 对象 (公开成员函数) |
operator= | 移动future对象 (公开成员函数) |
share | 从 *this 转移共享状态给 shared_future 并返回它 (公开成员函数) |
获取结果 | |
get | 返回结果 (公开成员函数) |
状态 | |
valid | 检查 future 是否拥有共享状态 (公开成员函数) |
wait | 等待结果变得可用 (公开成员函数) |
wait_for | 等待结果,如果在指定的超时间隔后仍然无法得到结果,则返回。 (公开成员函数) |
wait_until | 等待结果,如果在已经到达指定的时间点时仍然无法得到结果,则返回。 (公开成员函数) |
std::future_status
调用后wait_for或者wait_until返回的结果
enum class future_status
{ready, //成功timeout, //超时deferred //延迟
};
例子:
void getAnswer(std::promise<int> intPromise)
{std::this_thread::sleep_for(2s);intPromise.set_value(100);
}int main(int argc, char* argv[])
{std::promise<int> answerPromise;auto fut = answerPromise.get_future();std::jthread productThread(getAnswer, std::move(answerPromise));std::future_status status{};do{status = fut.wait_for(0.5s);std::cout << "结果未准备完成 \n\n";}while (status != std::future_status::ready);std::cout << std::format("answer is {}\n ", fut.get());
}
std::shared_future
类模板 std::shared_future
提供访问异步操作结果的机制,类似 std::future ,除了允许多个线程等候同一共享状态。不同于仅可移动的 std::future (故只有一个实例能指代任何特定的异步结果),std::shared_future
可复制而且多个 shared_future 对象能指代同一共享状态。
但即使使用std::shared_future
, 若我们从多个线程访问同一个对象, 就必须采取锁来保护以避免竞争
所以我们最好向每个线程传递std::shared_future对象的副本, 保证每个线程独有, 这样就不会发生数据竞争了
若每个线程通过其自身的 shared_future
对象副本访问,则从多个线程访问同一共享状态是安全的。
两种方式获取std::shared_future
std::shared_future<int> fut = answerPromise.get_future();
- std::future::share
std::promise<int> p;
std::future<int> f(p.get_future());
assert(f.valid()); future对象f有效
std::shared_future<int> sf(std::move(f));
assert(!f.valid()); 对象f不再有效
assert(sf.valid()); 对象sf开始生效
例子:
struct Div
{void operator()(std::promise<int>&& intPromise, int a, int b){intPromise.set_value(a / b);}
};struct Requestor
{void operator ()(std::shared_future<int> shaFut){std::lock_guard<std::mutex> coutGuard(coutMutex);std::cout << "threadId(" << std::this_thread::get_id() << "): ";std::cout << "20/10= " << shaFut.get() << std::endl;}
};int main()
{std::cout << std::boolalpha << std::endl;std::promise<int> divPromise;std::future<int> divResult = divPromise.get_future();std::cout << "divResult.valid(): " << divResult.valid() << std::endl;Div div;std::jthread divThread(div, std::move(divPromise), 20, 10);std::cout << "divResult.valid(): " << divResult.valid() << std::endl;std::shared_future<int> sharedResult = divResult.share();std::cout << "divResult.valid(): " << divResult.valid() << "\n\n";Requestor req;std::jthread sharedThread1(req, sharedResult);std::jthread sharedThread2(req, sharedResult);std::jthread sharedThread3(req, sharedResult);std::jthread sharedThread4(req, sharedResult);std::jthread sharedThread5(req, sharedResult);
}