自学内容网 自学内容网

57 C++ promise 在某一个线程中给A = 赋值,然后其他线程中可以获得这个A 的赋值

零 场景分析:

假设我们需要有一个线程是搞算法的,且每次需要场景的不同去算一次,这个算法花费的时间比较长。

一 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;

}


原文地址:https://blog.csdn.net/hunandede/article/details/135713532

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!