C++并发编程 等待与唤醒(2)

期望(std::future)可以用来等待其他线程上的异步结果, 其实例可以在任意时间引用异步结果.
C++包括两种期望, std::future(唯一期望) 和 std::shared_future(共享期望)
std::future 的实例只能与一个指定事件相关联.
std::shared_future 的实例能关联多个事件, 它们同时变为就绪状态, 并且可以访问与事件相关的任何数据.
在与数据无关的地方,可以使用 std::future<void> 与 std::shared_future<void> 的特化模板.
期望对象本身并不提供同步访问, 如果多个线程要访问一个独立的期望对象, 需要使用互斥体进行保护.

std::packaged_task

std::packaged_task 可包装一个函数或可调用的对象, 并且允许异步获取该可调用对象产生的结果, 返回值通过 get_future 返回的 std::future 对象取得, 其返回的 std::future 的模板类型为 std::packaged_task 模板函数签名中的返回值类型.
std::packaged_task 对象被调用时, 就会调用相应的函数或可调用对象, 将期望置为就绪, 并存储返回值.
std::packaged_task 的模板参数是一个函数签名, 如 int(std::string&, double*), 构造 std::packaged_task 实例时必须传入一个可以匹配的函数或可调用对象, 也可以是隐藏转换能匹配的.

std::packaged_task<std::string(const std::string&)> task([](std::string str) { std::stringstream stm; stm << "tid:" << std::this_thread::get_id() << ", str:" << str << std::endl; std::cout << stm.str(); std::this_thread::sleep_for(std::chrono::seconds(1)); return std::string("MSG:Hello"); }); std::future<std::string> f = task.get_future(); std::thread t(std::move(task), std::string("package task test")); t.detach(); // 调用 f.get 返回结果, 但是须阻塞等到任务执行完成 std::cout << "main tid:" << std::this_thread::get_id() << ", result: " << f.get() << std::endl;

std::promise

std::promise 类型模板提供设置异步结果的方法, 这样其他线程就可以通过 std::future 实例来索引该结果.

class SquareRoot { std::promise<double>& prom; public: SquareRoot(std::promise<double>& p) : prom(p) {} ~SquareRoot() {} void operator()(double x) { if (x < 0) { prom.set_exception(std::make_exception_ptr(std::out_of_range("x<0"))); } else { double result = std::sqrt(x); prom.set_value(result); } } }; std::promise<double> prom; SquareRoot p(prom); std::thread t(std::bind(&SquareRoot::operator(), &p, 1)); //std::thread t(std::bind(&SquareRoot::operator(), &p, -1)); std::future<double> f = prom.get_future(); try { double v = f.get(); std::cout << "value:" << v << std::endl; } catch (std::exception& e) { std::cout << "exception:" << e.what() << std::endl; } t.join();

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/3029fbd850a53a41f1ff3f0d82e1d1bb.html