class std::packaged_task被用来同时存储callable object,以及该callable object的返回值(也多是个异常).ios
#include <iostream> #include <thread> #include <future> #include <exception> int main() { std::packaged_task<int(const int&)> t1; //空的packaged_task即没有shared state,也没有callable object. std::packaged_task<int(const int&)> t2([](const int& number) { return 10; }); //构造函数,运行时候构建一个shared state,而且存储一个callable object进去. t1 = std::move(t2); //移动赋值运算符.这样一来t2中的shared state和callable object都转移到了t1中,t2不可再使用. std::future<int> result = t1.get_future(); std::thread t3(std::move(t1), 20); //此时t1处于无效状态. t3.detach(); //t3成为一个独立的线程. int value = result.get(); //若是t3内的callable object尚未执行完成,那么会阻塞调用result.get()的线程直到t3类的callable object调用完成. std::cout << "result: " << value << std::endl; return 0; }
----------------------------我是分割线------------------------------函数
std::packaged_task构造函数:this
packaged_task() noexcept; template <class Fn> explicit packaged_task (Fn&& fn); template <class Fn, class Alloc> explicit packaged_task (allocator_arg_t aa, const Alloc& alloc, Fn&& fn); packaged_task (const packaged_task&) = delete; //不支持拷贝. packaged_task (packaged_task&& x) noexcept;
1,默认构造函数构建一个std::packaged_task对象,即没有shared state,也没有callable object.spa
2,显式构造函数接受一个callable object初始化std::packaged_task。同时建立一个not ready的shared state.线程
3,被删除了的copy-constructor.code
4,移动构造函数,被移动的对象再也不可用,且当前对象得到被移动对象的callable object和shared state.对象
std::packaged_task::get_futureci
该函数返回一个std::future对象且该std::future与当前std::packaged_task共同使用同一个shared state.这样也就意味着,若是咱们对被返回出来的std::future调用get(),wait()等,若是std::packaged_task中的callable object未执行完成(也就是shared state还处于not ready状态),这样就会阻塞当前正在调用get()或者wait()的线程.get
future<Ret> get_future();
#include <iostream> #include <thread> #include <future> #include <string> int function(const int& number) { return number * 3; } int main() { std::packaged_task<int(const int&)> t1(function); std::future<int> result = t1.get_future(); //此时result 和 t1共享shared state. std::thread t2(std::move(t1), 20); //t1被移动变成不可用状态. t2.detach(); int value = result.get(); //这里调用get(),若是t2未执行完成(也就是shared state处于not ready状态),会block当前调用get()的线程(这里是main线程). std::cout << "value: " << value << std::endl; return 0; }
std::packaged_task::make_ready_at_thread_exitstring
调用当前std::packaged_task中的callable object以一个独立的线程运行该callable object,并转发参数进去callable object,可是callable object调用完成后并非当即把该std::packaged_task中的shared state设置为ready,而是直到该线程彻底结束的时候才设为ready.
void make_ready_at_thread_exit (args... args);
std::packaged_task::operator=
该std::packaged_task对象的拷贝赋值运算被删除了,也就是说std::packaged_task对象不能被拷贝.
可是能够被移动,被移动的std::packaged_task的shared state和callable object被移动当前std::packaged_task.被移动对象变成不可用的状态.
packaged_task& operator= (packaged_task&& rhs) noexcept; packaged_task& operator= (const packaged_task&) = delete;//拷贝构造函数被删除了.
std::packaged_task::operator()
调用当前对象内的callable object,并转发参数进去(不过须要注意的是若是咱们经过operator()调用callable object并非并行的):
1,若是当前std::packaged_task中的callable object执行完成,则callable object的返回值被存储到当前std::packaged_task的shared state中,且将该shared state的状态设置为ready.
2,若是当前的std::packaged_task中的callable object在执行过程当中抛出了异常,那么该异常会被捕获,也被存储在shared state中,而且该shared state被设置为ready.
#include <iostream> #include <thread> #include <future> #include <string> #include <utility> class Object { private: int number; public: Object(); ~Object() = default; int& operator()(const int& number)noexcept; }; Object::Object() :number(1) { // } int& Object::operator()(const int& number)noexcept { this->number = 20 * number; std::this_thread::sleep_for(std::chrono::seconds(2)); return (this->number); } class MyObject { private: int number; public: inline MyObject():number(1){} ~MyObject() = default; int getNumber(const int& num)noexcept { return (this->number * num); } }; int function(const int& number) { return number * 3; } int main() { //callable object case 1: std::packaged_task<int(const int&)> t1(function); std::future<int> result = t1.get_future(); //此时result 和 t1共享shared state. std::thread t2(std::move(t1), 20); //t1被移动变成不可用状态. t2.detach(); int value = result.get(); //这里调用get(),若是t2未执行完成(也就是shared state处于not ready状态),会block当前调用get()的线程(这里是main线程). std::cout << "value: " << value << std::endl; //callable object case 2: try { Object object; std::packaged_task<int& (const int&)noexcept> t3(object); std::future<int&> result1 = t3.get_future(); //t3(20); //调用callable object可是并不会并行调用. std::thread t4(std::move(t3), 20); t4.detach(); std::cout << " test " << std::endl; int value1 = result1.get(); std::cout << "value1: " << value1 << std::endl; }catch (const std::exception& e) { std::cerr << "exception!" << std::endl; } //callable object case 3: MyObject myObject; std::function<int(const int&)> memberFunction = std::bind(&MyObject::getNumber, &myObject, std::placeholders::_1); std::packaged_task<int(const int&)> t5(memberFunction); std::future<int> result2 = t5.get_future(); std::thread t6(std::move(t5), 20); t6.detach(); int value2 = result2.get(); std::cout << "value2: " << value2 << std::endl; return 0; }
std::packaged_task::reset
当咱们执行完了callable object(不管是经过当前std::packaged_task的operator(),仍是经过std::thread),当前std::packaged_task对象内的shared state都被设置为了ready,这样也就形成了咱们经过调用当前std::packaged_task对象的get_future()函数得到的std::future只能get()一次,
那么咱们想要再次执行该callable object怎么办呢?这个时候就须要调用当前std::packaged_task对象的reset()函数了给当前std::packaged_task对象建立一个新的shared state且处于not ready状态.
void reset();
#include <iostream> #include <thread> #include <future> #include <string> int getNumber(const int& number) { return number * 20; } int main() { std::packaged_task<int(const int&)> package(getNumber); std::future<int> result = package.get_future(); package(20); int value = result.get(); std::cout << "value(now shared state is ready): " << value << std::endl; std::cout << "reset the shared state." << std::endl; package.reset(); std::future<int> result2 = package.get_future(); std::thread t2(std::move(package), 40); //注意这里用了std::move(),package对象会再也不可用. t2.detach(); int value2 = result2.get(); std::cout << " value2(now share state is again ready): " << value2 << std::endl; return 0; }