Multi thread: std::promise
2016-05-14 00:00
155 查看
前面我们了解到可以使用std::shared_future/std::shared_future在多个其他线程中处理另外一个线程的函数的返回结果.
那么疑问来了,我们要怎样在多线程之间传递数据呢?
demo1 :std::promise在线程之间传递参数/处理异常:
最好自己跑一下上面的例子再看下面的内容
在向线程传递std::promise对象作为参数的时候尽量用std::ref.
1,因为std::promise对象是不支持拷贝的.
2,只有以by-reference的形式传递我们才能改变原std::promise对象的shared state.
std::promise的构造函数:
1,构造函数在构建std::promise的时候构建一个新的shared state.
2,移动构造函数从另外的std::promise对象获得shared state,被移动的std::promise对象不再具有shared state.
std::promise内的shared state存放一个相应类型的值或者异常.
std::promise::get_future
该函数返回一个std::future对象,且std::future对象与当前std::promise共用一个shared state:
1, 也就是说当当前std::promise对象的shared state被设为ready的时候,被返回出来的std::future对象的shared state也被设置为ready.
2,也就是说我们可以通过被返回的std::future对象获得std::promise中的值和异常.
std::promise::operator=
虽然是operator=但是只能使用移动赋值运算符.抛弃当前std::promise内的shared state,获得rhs的shared state,且被移动的std::promise对象变成不能使用状态,否则抛出std::future_error异常.
std::promise::set_exception
exception_ptr是一个智能指针,存储一个指向异常的智能指针到std::promise的shared state,
且当前shared state的状态会立即被设置为ready.
std::promise::set_value
设置一个值到存储到当前std::promise的shared state,且立即将shared state的状态设置为ready.
std::promise::set_exception_at_thread_exit
设置一个存储异常的智能指针存储到当前std::promise对象的shared state里,但是并没有立即把该shared state设置为ready,而是直到当前线程完成退出的时才被设置为ready.
std::promise::set_value_at_thread_exit
设置一个值存储到当前std::promise对象的shared state里,但是并没有立即把该shared sate设置为ready,而是直到当前线程结束退出的时候才被设置为ready.
总结:
如果我们通过当前std::promise对象的get_future()得到一个std::future,由于是得到的std::future和当前std::promise对象是共用一个shared state的,因此当我们想要通过std::future对象的get()获得存储于shared state状态中的值的时候,如果这个shared state没有被设置为ready,就会阻塞正在调用该std::future对象get()函数的线程.
那么疑问来了,我们要怎样在多线程之间传递数据呢?
demo1 :std::promise在线程之间传递参数/处理异常:
#include <iostream> #include <thread> #include <chrono> #include <future> #include <utility> #include <exception> #include <stdexcept> #include <string> void doSomething(std::promise<std::string>& p) { try { std::cout << "read char('x' for exception): "; char c = std::cin.get(); if (c == 'x') { throw std::runtime_error(std::string("runtime_error")); } std::string str = std::string("char ") + c + std::string(" read"); p.set_value(std::move(str)); p.set_value(std::string("shihuawoaini")); }catch (...) { p.set_exception(std::current_exception()); } } int main() { try { std::promise<std::string> p; std::thread t1(doSomething, std::ref(p)); //注意这里是以引用的形式传递的std::promise对象. //只有以引用的形式我们才能改变std::promise中的shared state的状态,而且本事std::promise是不支持拷贝的 t1.detach(); std::future<std::string> f(p.get_future()); //此时的std::future和前面的std::promise共用同一个shared state; std::cout << "result: " << f.get() << std::endl; //注意这里的get(),当std::future的shared state未被设置为ready的时候会block mian线程.直到被设置为ready. }catch (const std::exception& e) { std::cerr << "EXCEPTION: " << e.what() << std::endl; }catch (...) { std::cerr << "EXCEPTION: " << std::endl; } }
最好自己跑一下上面的例子再看下面的内容
在向线程传递std::promise对象作为参数的时候尽量用std::ref.
1,因为std::promise对象是不支持拷贝的.
2,只有以by-reference的形式传递我们才能改变原std::promise对象的shared state.
std::promise的构造函数:
1,构造函数在构建std::promise的时候构建一个新的shared state.
2,移动构造函数从另外的std::promise对象获得shared state,被移动的std::promise对象不再具有shared state.
std::promise内的shared state存放一个相应类型的值或者异常.
promise(); //默认构造函数. template <class Alloc> promise (allocator_arg_t aa, const Alloc& alloc);//自己设置内存分配器的构造函数. promise (const promise&) = delete; //拷贝构造函数被删除掉了. promise (promise&& x) noexcept;//移动构造函数.
std::promise::get_future
该函数返回一个std::future对象,且std::future对象与当前std::promise共用一个shared state:
1, 也就是说当当前std::promise对象的shared state被设为ready的时候,被返回出来的std::future对象的shared state也被设置为ready.
2,也就是说我们可以通过被返回的std::future对象获得std::promise中的值和异常.
future<T> get_future();
std::promise::operator=
虽然是operator=但是只能使用移动赋值运算符.抛弃当前std::promise内的shared state,获得rhs的shared state,且被移动的std::promise对象变成不能使用状态,否则抛出std::future_error异常.
promise& operator= (promise&& rhs) noexcept; promise& operator= (const promise&) = delete; //拷贝复制运算符被删除了.
std::promise::set_exception
exception_ptr是一个智能指针,存储一个指向异常的智能指针到std::promise的shared state,
且当前shared state的状态会立即被设置为ready.
void set_exception (exception_ptr p);
std::promise::set_value
设置一个值到存储到当前std::promise的shared state,且立即将shared state的状态设置为ready.
void set_value (const T& val); void set_value (T&& val); void promise<R&>::set_value (R& val); // when T is a reference type (R&) void promise<void>::set_value (void); // when T is void
std::promise::set_exception_at_thread_exit
设置一个存储异常的智能指针存储到当前std::promise对象的shared state里,但是并没有立即把该shared state设置为ready,而是直到当前线程完成退出的时才被设置为ready.
void set_exception_at_thread_exit (exception_ptr p);
std::promise::set_value_at_thread_exit
设置一个值存储到当前std::promise对象的shared state里,但是并没有立即把该shared sate设置为ready,而是直到当前线程结束退出的时候才被设置为ready.
void set_value_at_thread_exit (const T& val); void set_value_at_thread_exit (T&& val); void promise<R&>::set_value_at_thread_exit (R& val); // when T is a reference type (R&) void promise<void>::set_value_at_thread_exit (void); // when T is void
总结:
如果我们通过当前std::promise对象的get_future()得到一个std::future,由于是得到的std::future和当前std::promise对象是共用一个shared state的,因此当我们想要通过std::future对象的get()获得存储于shared state状态中的值的时候,如果这个shared state没有被设置为ready,就会阻塞正在调用该std::future对象get()函数的线程.
相关文章推荐
- 招聘时面试官可能会问的一些小问题总结(一)
- mybatis 多层select示例
- The operation couldn’t be completed. (LaunchServicesError error 0.)
- 三级联动数据
- phonegap cordova 环境搭建及安装
- 编程上的那点事情儿
- 读书笔记---《如何高效学习》
- MappedByteBuffer 替代unmap方案
- visual C++ & Makefile
- 语法分析器自动生成工具一览
- POI
- JAVA读文件和写文件的的代码模版
- bat命令遍历文件和bat参数说明
- 线程池 API (转)
- window linux IPC ftok BY_HANDLE_FILE_INFORMATION
- 共享内存
- POI Excel 冷冻线
- Android 项目框架 使用MVP开发
- 托管程序调用非托管dll问题总结
- ini文件