零 场景分析:
假设我们需要有一个线程是搞算法的,且每次需要场景的不同去算一次,这个算法花费的时间比较长。
一 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;}