C++11多线程期望

**

前言

**
前面所写的多线程处理的代码中,线程入口函数都是无返回值的,并且在传递参数时特别麻烦。
现在有了另外的解决方案,使用future期望,为了处理线程间的变量的传递,其设定了共享状态标志future_status。

等待一次事件
你等了一辆出租车后就坐车走了,不需要再等第二辆,也就是说只要有一辆过来就行,这就叫等待一次事件。
在期望中,变量最多只能set一次和get一次。

如何拥有共享状态?< future >头文件里有啥?

Providers类:promise,packaged_task
Futures类:future,shared_future
Providers函数: async()
其他类型:future_error,future_errc,future_status,launch

promise类

promise对象可以保存某一类型T的值,该值可被future对象读取(可能在另外一个线程中),因此 promise 也提供了 一种线程同步的手段。
在 promise 对象构造时可以和一个共享状态(通常)相关联,并可以在相关联的共享状态上保存一个类型为T的值。
可以通过get_future来获取与该promise 对象相关联的 future对象,调用该函数后,两个对象共享状态同步
promise对象是异步Provider,可以在某一时刻设置共享状态的值
future对象可以异步返回共享状态的值,或者在必要的情况下阻塞调用者并等待共享状态标志变为ready,然后才能获取共享状态的值

void test01(){
	promise<int> p;  //生成一个promise对象
	future<int> f = p.get_future();//和future关联

	auto lam = [](future<int>& f) {
		int x = f.get();//获取共享状态的值
		cout << "value = " << x << "\n";
	};
	thread t( lam, std::ref(f));

	p.set_value(10);//设置共享状态的值,此处和线程 t 保持同步

	t.join();
}

如果是把promise对象赋值给一个新的promise对象,线程入口函数就不能有参数


promise<int> p;
void test02() {

	auto lam = []() {
		future<int> f = p.get_future();
		int x = f.get();
		cout << "value = " << x << endl;
	};

	thread t1(lam);
	p.set_value(10);
	t1.join();


	p = promise<int>();  //p被move赋值给一个新的promise对象

	thread t2(lam);
	p.set_value(20);
	t2.join();


}


set_exception设置异常

void get(promise<int>& p) {
	int x;
	cout << "please,enter an integer value = ";
	cin.exceptions(ios::failbit);//throw on failbit
	try {
		cin >> x;
		p.set_value(x);
	}
	catch (exception&) {
		p.set_exception(current_exception());
	}

}

void print(future<int>& f){
	try {
		int x = f.get();
		cout << "value = " << x << endl;
	}
	catch (exception& e) {
		cout << "[exception caught >> " << e.what() << "]\n";
	}
}
void test03() {

	promise<int> p;
	future<int> f = p.get_future();

	thread t1(get, std::ref(p));
	thread t2(print, std::ref(f));

	t1.join();
	t2.join();

}


packaged_task类

packaged_task对象内部包含两个基本元素:

  1. 被包装的任务,即一个可调用对象
  2. 共享状态,用于保存任务的返回值。可以通过future对象来达到异步访问共享状态的效果
void test01() {

	auto lam = [](int from,int to)->int {
		for (int i = from; i != to; i--) {
			cout << i << "\n";
			this_thread::sleep_for(chrono::seconds(1));
		}
		cout << "Finished!\n";
		return from - to;
	};

	//传递一个函数类型,返回类型(参数类型,参数类型. .. )
	packaged_task<int(int, int)> task(lam);//设置packaged_task
	future<int> f = task.get_future();//获得与packaged_task共享状态相关联的 future对象

	thread t(std::move(task), 10, 0);//创建一个新线程完成计数任务

	int x = f.get();
	cout << "the lam lasted for " << x << " seconds\n";
	t.join();

}


std::move转移所有权、重置packaged_task对象的共享状态(保留了之前包装的任务)

void test02() {

	auto lam = [](int x) {return 3 * x; };

	packaged_task<int(int)> task(lam);
	future<int> f = task.get_future();
	thread(std::ref(task), 100).detach();//分离    这里千万不要传递task所有权
	cout << f.get() << endl;


	task.reset();

	f = task.get_future();
	thread(std::move(task), 200).detach();//分离
	cout << f.get() << endl;


}

async()

不用thread对象也可以创建线程,

扫描二维码关注公众号,回复: 5635181 查看本文章
#include<chrono>

bool is_prime(int x) {
	for (int i = 2; i < x; ++i)
		if (x%i == 0)
			return false;
	return true;
}
void test01() {

	future<bool> f = async(is_prime, 7);
	cout << "checking, please wait";
	chrono::milliseconds s(1000);
	while (f.wait_for(s) == future_status::timeout)
		cout << " . ";
	bool x = f.get();
	cout << "\7 " << (x ? "is" : "is not") << " prime.\n";

}

future_status::ready
共享状态的标志已经变成ready,即Provider在共享状态上设定了值或设定了异常

future_status::timeout
超时,在规定的时间内共享状态的标志没有变成ready

future_status::deferred
共享状态包含一个deferred函数

void print(char c, int ms) {
	for (int i = 0; i < 10; i++) {
		this_thread::sleep_for(chrono::milliseconds(ms));
		cout << c;
	}
}
void test04() {

	cout << " with launch::async >> \n";

	future<void> f = async(launch::async, print, '*', 100);
	future<void> b = async(launch::async, print, '@', 200);


	f.get();
	b.get();

	cout << "\n\n with launch::deferred >> \n";


	f = async(launch::deferred, print, '*', 100);
	b = async(launch::deferred, print, '@', 200);


	f.get();
	b.get();

}

猜你喜欢

转载自blog.csdn.net/weixin_41374099/article/details/88724671
今日推荐