零 场景分析:
假设我们需要有一个线程是搞算法的,且每次需要场景的不同去算一次,这个算法花费的时间比较长。
一 promise C++中文档的说明
std::promise 在标头 <future> 定义 template< class R > class promise; (1) (C++11 起) template< class R > class promise<R&>; (2) (C++11 起) template<> class promise<void>; (3) (C++11 起) 1) 空模板 2) 非 void 特化,用于在线程间交流对象 3) void 特化,用于交流无状态事件 类模板 std::promise 提供存储值或异常的设施,之后通过 std::promise 对象所创建的 std::future 对象异步获得结果。注意 std::promise 只应当使用一次。 每个 promise 与共享状态关联,共享状态含有一些状态信息和可能仍未求值的结果,它求值为值(可能为 void )或求值为异常。 promise 可以对共享状态做三件事: ?使就绪: promise 存储结果或异常于共享状态。标记共享状态为就绪,并解除阻塞任何等待于与该共享状态关联的 future 上的线程。 ?释放: promise 放弃其对共享状态的引用。若这是最后一个这种引用,则销毁共享状态。除非这是 std::async 所创建的未就绪的共享状态,否则此操作不阻塞。 ?抛弃: promise 存储以 std::future_errc::broken_promise 为 error_code 的 std::future_error 类型异常,令共享状态为就绪,然后释放它。 promise 是 promise-future 交流通道的“推”端:存储值于共享状态的操作同步于(定义于 std::memory_order )任何在共享状态上等待的函数(如 std::future::get )的成功返回。其他情况下对共享状态的共时访问可能冲突:例如, std::shared_future::get 的多个调用方必须全都是只读,或提供外部同步。
二 普通顺序调用启动
三 普通函数线程启动
四 类成员函数线程启动
class Teacher179 { public: mutex mymutex; list<int> mylist; public: int readfunc(string &tempstr) { for (size_t i = 0; i < 10; i++) { mymutex.lock(); cout << "read func tempstr = " << tempstr << " i = " << i << " threadid = " << this_thread::get_id() << " &tempstr = " << &tempstr << " tempstr = " << tempstr << endl; mymutex.unlock(); } return 10; } int writefunc(const int &tempdouble) { for (size_t i = 0; i < 10; i++) { mymutex.lock(); cout << "write func tempdouble = " << tempdouble << " i = " << i << " threadid = " << this_thread::get_id() << " &tempdouble = " << &tempdouble << " tempdouble = " << tempdouble << endl; mymutex.unlock(); } return (int)tempdouble; } double promisefunc(promise<int> &resultint, string strsource) { cout << "teacher179 promisefunc start " << endl; // 计算完毕后,我们假设计算结果是1000,给resultint赋值 resultint.set_value(1000); cout << "teacher179 promisefunc end " << endl; return 3.14; } public: Teacher179() { cout << "Teacher179 构造方法被执行" << endl; } ~Teacher179() { cout << "Teacher179 析构方法被执行" << endl; } Teacher179(const Teacher179& tea) { cout << "Teacher179 copy 构造 被执行" << endl; } }; //该方法,返回值是double,参数是string,在函数内部可以给一个 int赋值。赋值后的数据可以通过 resultint的实参.getfuture()获得 double promisefunc(promise<int> &resultint,string strsource) { cout << "promisefunc start " << endl; // 计算完毕后,我们假设计算结果是1000,给resultint赋值 resultint.set_value(1000); cout << "promisefunc end " << endl; return 3.14; } // promise ,在某一个线程中给A 赋值,然后其他线程中可以使用这个A 的值 void main() { //直接调用 promise<int> promi; promisefunc(promi, "nihao"); future<int> fu = promi.get_future(); cout << fu.get() << endl; //启动线程调用 string str2 = "how are you"; promise<int> promi2; thread mythread10(promisefunc,ref(promi2),str2); mythread10.join(); future<int> fu5 = promi2.get_future(); cout<<fu5.get()<<endl; //async 线程启动 string str3 = "chinabank"; promise<int> promi3; //注意,这里ayync的返回值是线程入口启动函数的返回值是double, //promi3.get_future()的返回值是线程中想要赋值的数据的返回值 future<double> fu6 = async(launch::async, promisefunc, ref(promi3), ref(str3)); future<int> fu7 = promi3.get_future(); cout << fu6.get() << endl;; cout << fu7.get() << endl;; //类成员函数 cout << "teacher179start" << endl; string str10 = "teacher179"; promise<int> promi100; Teacher179 tea; thread mythread100(&Teacher179::promisefunc, &tea, ref(promi100), ref(str10)); mythread100.join(); cout<<promi100.get_future().get()<<endl; cout << "teacher179start2" << endl; string str11 = "teacher179111"; promise<int> promi11; Teacher179 tea1; future<double> fu11 = async(launch::async, &Teacher179::promisefunc, &tea, ref(promi11), ref(str11)); future<int> fu12 = promi11.get_future(); cout << fu11.get() << endl; cout << fu12.get() << endl; }