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;

}