C++多线程高并发,packaged_task,future , promise

首先说packaged_task,future

他到底是个什么意思呢?其实写下来感觉就是一个存方法的容器,也可以理解为给方法娶了一个别名,下面直接上代码,看完基本上就能从用法和本质上理解个差不多了

玩法一,使用线程接收packaged_task,使用future接收结果
//线程入口函数
void threadEntryFunc(std::promise<int> &myPromise , int param1)
{
	//do some arithmetic , and spend 2 seconds
	param1 *= 100;
	std::chrono::milliseconds dura(2000);
	std::this_thread::sleep_for(dura);
	//保存结果,保存到了这个promise对象中,外面能取到这个值,是因为这个promise是一个引用
	myPromise.set_value(param1);
	return;
}

int main()
{
	std::cout << "the main thread id is " << std::this_thread::get_id() << std::endl;

	
	//声明packaged_task<returnType(needType)> name(threadEntryFuncName)
	//比如下面就是返回的是int类型的,也需要传递进去一个int类型的
	//所以是<int(int)>
	std::packaged_task<int(int)> myPackagedTask(threadStepInMethod);
	std::thread myThread(std::ref(myPackagedTask),6);
	myThread.join();
	//返回一个future对象,直接就能根据future.get()得到返回的结果
	std::future myFuture = myPackagedTask.get_future();
	std::cout << "方式二执行结果:" << myFuture.get() << std::endl;
}
玩法二,使用lambda表达式进行线程入口函数的编写
int main()
{
//创建packaged_task的时候,直接进行lambda的编写
std::packaged_task<int(int)> myPackagedTask([](int i) {
	std::cout << "thread start " << std::endl;
	std::cout << "线程id:" << std::this_thread::get_id() << std::endl;
	std::chrono::milliseconds dura(5000);
	std::this_thread::sleep_for(dura);
	std::cout << " thread end " << std::endl;
	return i * 100;
	});
	std::thread myThread(std::ref(myPackagedTask),1);
	myThread.join();
	//使用future对象接收返回结果
	std::future myFuture = myPackagedTask.get_future();
	std::cout << "the result is " << myFuture.get() << std::endl;
}
玩法三,究其根本,packaged_task到底是个什么玩意儿?
void threadEntryFunc(std::promise<int> &myPromise , int param1)
{
	//do some arithmetic , and spend 2 seconds
	param1 *= 100;
	std::chrono::milliseconds dura(2000);
	std::this_thread::sleep_for(dura);
	//保存结果,保存到了这个promise对象中,外面能取到这个值,是因为这个promise是一个引用
	myPromise.set_value(param1);
	return;
}


int main()
{
	//声明packaged_task,
	std::packaged_task<int(int)> myPackagedTask(threadEntryFunc);
	//这里传进去参数,当然也可以选择创建的时候直接进行参数的传递
	myPackagedTask(666);
	//直接引用结果,也不创建线程,就直接调取packaged_task里面的方法
	std::future myFuture= myPackagedTask.get_future();
	std::cout << "the result is " << myFuture.get() << std::endl;
}

这个就有点儿意思了,这就是本质的问题了
运行结果如下
在这里插入图片描述
通过运行结果分析可知,直接引用,他就是一个函数调用,线程都没有创建,只不过用.get_future() 纯粹是因为要得到这个函数的返回结果,凑巧这个对象里面也有这个得到future的函数罢了 这一点和java里面的多线程很像,你重写了Thread的run()方法,但是调用时只是调用了run方法 而没有使用启动线程的start()方法,所以根本没有启动新的线程 一样的道理

玩法四,更深一层次的应用,使用容器装packaged_task
int main()
{
	//创建一个装packaged_task<int(int)>的容器
	std::vector<std::packaged_task<int(int)>> myVector;
	//声明packaged_task<int(int)>对象
	std::packaged_task<int(int)> myPackagedTask(threadStepInMethod);
	//将对象放入容器
	myVector.push_back(std::move(myPackagedTask));
	//从容器中取出对象
	auto iter = myVector.begin();
	//转化为packaged_task<int(int)>对象
	//*iter就是说的是指针指向的对象/值,然后使用move,使左值变为右值
	std::packaged_task<int(int)> myPackagedTaskReceived = std::move(*iter);
	//传递进去参数
	myPackagedTaskReceived(100);
	//得到结果
	std::cout << "the result is " << myPackagedTaskReceived.get_future().get() << std::endl;
}

promise,在线程之间传递参数

void threadEntryFunc(std::promise<int> &myPromise , int param1)
{
	//do some arithmetic , and spend 2 seconds
	param1 *= 100;
	std::chrono::milliseconds dura(2000);
	std::this_thread::sleep_for(dura);
	//保存结果,保存到了这个promise对象中,外面能取到这个值,是因为这个promise是一个引用
	myPromise.set_value(param1);
	return;
}


void threadEntryFunc2(std::future<int> &myParamFuture)
{
	auto result = myParamFuture.get();
	std::cout << "线程二中得到结果:" << result << std::endl;
}

int main()
{
	//promise对象的声明
	std::promise<int> myPromise;
	std::thread myThread(threadEntryFunc, std::ref(myPromise), 10);
	myThread.join();
	std::future myFuture = myPromise.get_future();
	
	//创建第二个线程,在第二个线程中接收promise返回的结果
	std::thread myThread2(threadEntryFunc2, std::ref(myFuture));
	myThread2.join();
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值