【C++多线程系列】【十】future与promise

当两个线程间需要传递数据时,可以使用promise与future来实现。

线程A通过promise.setvalue来设置数据,线程B通过promise的get_future获取future后,从future中获取数据。future写用法与前面博文用法一致。

【一】设置数据与获取数据

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;

void f(future<int> &fu)
{
	cout << fu.get() << endl;
}


int main(int argc, int * argv[])
{
	promise<int> pro;
	future<int> fu = pro.get_future();

	thread t1(f, std::ref(fu));
	
	pro.set_value(10);

	t1.join();
	cout << "main" << endl;
	system("pause");
}

结果如下:

220333_On32_3800567.png

【二】只get,不set

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;

void f(future<int> &fu)
{
	cout << fu.get() << endl;
}


int main(int argc, int * argv[])
{
	promise<int> pro;
	future<int> fu = pro.get_future();

	thread t1(f, std::ref(fu));
	
	//pro.set_value(10);

	t1.join();
	cout << "main" << endl;
	system("pause");
}

子线程会一直阻塞在fu.get上

【三】set一次,get多次

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;

void f(future<int> &fu)
{
	cout << fu.get() << endl;
	cout << fu.get() << endl;
}


int main(int argc, int * argv[])
{
	promise<int> pro;
	future<int> fu = pro.get_future();

	thread t1(f, std::ref(fu));
	
	pro.set_value(10);

	t1.join();
	cout << "main" << endl;
	system("pause");
}

程序会运行失败。当使用promise set_value时,future便处于ready状态,可以get到值,第二次get时,由于future被get了一次,不可以被get第二次,所以第二次get会失败。future设计上,就是只能get一次

同时,promise只能被set一次,不能被set第二次。

如下程序会崩溃

int main(int argc, int * argv[])
{
	promise<int> pro;
	future<int> fu = pro.get_future();

	//thread t1(f, std::ref(fu));
	
	pro.set_value(10);
	pro.set_value(10);

	//t1.join();
	cout << "main" << endl;
	system("pause");
}

如果只set,而没有get,是没有问题的

int main(int argc, int * argv[])
{
	promise<int> pro;
	future<int> fu = pro.get_future();

	//thread t1(f, std::ref(fu));
	
	pro.set_value(10);
	//pro.set_value(10);

	//t1.join();
	cout << "main" << endl;
	system("pause");
}

【四】一个线程set,两个线程get

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;

void f(future<int> &fu)
{
	cout << "f"<<fu.get() << endl;
	//cout << fu.get() << endl;
}
void f2(future<int> &fu)
{
	cout << "f2"<<fu.get() << endl;
	//cout << fu.get() << endl;
}


int main(int argc, int * argv[])
{
	promise<int> pro;
	future<int> fu = pro.get_future();

	thread t1(f, std::ref(fu));
	thread t2(f, std::ref(fu));
	
	pro.set_value(10);
	//pro.set_value(10);

	t1.join();
	t2.join();
	cout << "main" << endl;
	system("pause");
}

该程序会崩溃。

 

【五】注意点。join的位置应该在set之前,否则子线程会由于没有数据而一直等待

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;

void f(future<int> &fu)
{
	cout << "f"<<fu.get() << endl;
}



int main(int argc, int * argv[])
{
	promise<int> pro;
	future<int> fu = pro.get_future();

	thread t1(f, std::ref(fu));

	t1.join();
     
    pro.set_value(10);  // set在join之后,子线程会一直等待,而主线程也一直在等待子线程运行结束后才会set,所以形成死循环。

	cout << "main" << endl;
	system("pause");
}

 

 

总结:使用future与promise进行线程间数据共享,实际上是一种一次性消费,仅支持一对一,而且是一次性消费,不能再使用第二次。

转载于:https://my.oschina.net/u/3800567/blog/1807065

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值