多线程学习笔记5

6 篇文章 7 订阅
6 篇文章 0 订阅
std::async
std::future
#include<future>

std::async是一个函数模板 , 用来启用一个异步任务 , 启动起来之后 , 返回一个std::future(类模板)对象

启动一个异步任务 : 创建一个线程并开始执行对应的线程入口函数 , 返回一个std::future对象

std::future里面就含有线程入口函数返回的结果( 线程返回结果 ) , 我们通过调用它的成员函数get()来获取

std::future提供了一种访问异步操作结果的机制 , 这个结果可能无法马上拿到 , 在将来线程执行结束后就能拿到

int run1(){
	for(int i=0;i<=1e4;i++){
		cout<<"thread_id : "<<std::this_thread::get_id()<<endl;
	}
	return 666;
}

int main(){
	cout<<"main_thread_id : "<<std::this_thread::get_id()<<endl;
	std::future<int> result = std::async(run1);//创建一个线程并开始执行
	cout<<"continue...!"<<endl;
	cout<<result.get()<<endl;//卡在这里,等待拿到结果
	//get()只能调用一次
	//result.wait();//等待线程返回 , 本身并不返回结果
	return 0;
}
class A{
public:
	int run1(int tem){
		for(int i=0;i<=1e4;i++){
			cout<<"thread_id : "<<std::this_thread::get_id()<<endl;
		}
		return 666;
	}		
};
int main(){
    A a;
	int tem=2;
    std::future<int> result = std::async(A::run1,ref(a),tem);
    cout<<result.get()<<endl;
    return 0;
}
std::launch::deferred

通过向std::async()传递一个参数 , 该参数类型是std::lunnch类型(枚举类型) , 来达到一些特殊目的

std::launch::deferred表示线程入口函数调用被延迟到std::futurewait()或者get()函数调用时才执行

如果wait()或者get()没有被调用 , 那么线程就不创建

std::launch::deferred : 延迟调用 , 没有线程创建 , 直接在主函数中调用线程入口的函数

std::future<int> result = std::async(std::launch::deferred,A::run1,ref(a),tem);
std::launch::async

在调用async函数的时候就开始创建线程

系统默认标记 , 就和不写是一样的

std::future<int> result = std::async(std::launch::async,A::run1,ref(a),tem);
std::packaged_task

打包任务 , 把任务包装起来

是一个类模板 , 它的模板参数是 各种可调用对象 ; 通过std::packad_task来把各种可调用对象包装起来 , 方便将作为线程入口函数调用

packaged_task包装起来的可调用对象还可以直接调用 , 所以从这个角度来讲 , packed_task对象 , 也是一个可调用对象

#include<iostream>
#include<cstdio>
#include<thread>
#include<cstdlib>
#include<vector>
#include<list>
#include<queue>
#include<mutex>
#include<chrono>
#include<condition_variable>
#include<future>
using namespace std;

int run1(int tem){
	cout<<"thread_id : "<<std::this_thread::get_id()<<endl;
	return 666;
}		

int main(){
	cout<<"main_thread_id : "<<std::this_thread::get_id()<<endl;
	std::packaged_task<int(int)> myjob(run1);//我们把函数mythread通过packaged_task包装起来,当然也可以写成lamda表达式
	std::thread ttt(std::ref(myjob),1);//线程直接开始执行 , 第二个参数 作为线程入口函数的参数
	ttt.join();//等待线程执行完毕
	std::future<int> result = myjob.get_future();//std::future对象里包含有线程入口函数的返回结果,result保存了myjob的返回值
	cout<<result.get()<<endl;
	return 0;
}
int run1(int tem){
	cout<<"thread_id : "<<std::this_thread::get_id()<<endl;
	return 666;
}		

int main(){
	cout<<"main_thread_id : "<<std::this_thread::get_id()<<endl;
	std::packaged_task<int(int)> myjob(run1);//我们把函数mythread通过packaged_task包装起来,当然也可以写成lamda表达式
	myjob(3);//直接调用,直接在线程里执行
	std::future<int> result = myjob.get_future();//std::future对象里包含有线程入口函数的返回结果,result保存了myjob的返回值
	cout<<result.get()<<endl;
	return 0;
}
std::promise

类模板

我们能够在某个线程中给它赋值 , 然后可以在其他线程中 , 把这个值取出来使用

#include<iostream>
#include<cstdio>
#include<thread>
#include<cstdlib>
#include<vector>
#include<list>
#include<queue>
#include<mutex>
#include<chrono>
#include<condition_variable>
#include<future>
using namespace std;

void run1(std::promise<int> &p,int tem){
	cout<<"thread_id : "<<std::this_thread::get_id()<<endl;
	tem++;
	tem=((1<<tem) | tem);
	for(int i=0;i<1e3;i++){
		cout<<"i love China!"<<endl;
	}
	p.set_value(tem);//将结果保存到p对象中
}		
void run2(std::future<int> &ful){
	cout<<ful.get()<<endl;//直到线程run1执行结束才开始执行
	cout<<"thread_id : "<<std::this_thread::get_id()<<endl;
}

int main(){
	cout<<"main_thread_id : "<<std::this_thread::get_id()<<endl;
	std::promise<int> mypro;//声明一个std::promise对象,保存值类型为int
	std::thread tt(run1,std::ref(mypro),3);
	//tt.join();

	std::future<int> ful = mypro.get_future();//promise和future绑定,用于获取线程返回值
	std::thread tt2(run2,std::ref(ful));
	tt.join();
	tt2.join();
	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值