C++ - 多线程之带返回值的线程处理函数

1. 使用 async 函数创建线程

1.1 使用步骤

  1. 使用async函数启动一个异步任务(创建线程,并且执行线程处理函数),返回future对象
  2. 通过future对象中get()方法获取线程处理函数的返回值

1.2 基本数据类型作为返回值

#include <iostream>
#include <thread>
#include <future>
using namespace std;
 
//1.1 普通类型返回值
int returnValue() {
	return 666;
}
void test01() {
	future<int> res = async(returnValue);
	cout << res.get() << endl;
}
 
int main() {

	test01();
	return 0;
}

1.3 结构体类型数据作为返回值

#include <iostream>
#include <thread>
#include <future>
#include <string>
#include <chrono>
using namespace std;
 
//结构体类型返回值
struct Person {
	int age;
	string name;
	friend ostream& operator<<(ostream& out, Person& person);
};
// << 运算符重载
ostream& operator<<(ostream& out, Person& person) {
	out << person.age << "\t" << person.name << endl;
	return out;
}
Person returnPerson() {
	Person person = { 18,"张飞" };
	return person;
}
void test02() {
	future<Person> res = async(returnPerson);
	Person person = res.get();
	cout << person << endl;
}
int main() {

	test02();
	return 0;
}

1.4 带返回值的类的成员函数作为线程处理函数

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

//1.3 带返回值的类成员函数充当线程处理函数
class MM {
public:
	int mmThreadFunc(int num) {
		cout << "子线程id: " << this_thread::get_id() << endl;
		num *= 10;
		//延时
		chrono::microseconds duration(1000); //1000微秒
		this_thread::sleep_for(duration);
		return num;
	}
protected:
private:
};
void test03() {
	MM mm;
	future<int> res = async(&MM::mmThreadFunc, &mm, 5);
	cout << res.get() << endl;
}

int main() {

	test03();
	return 0;
}

 

1.5 async的其它两个参数

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

//1.4 async 的其它参数 ()
//launch::async		: 创建线程,执行线程处理函数
//launch::deferred	: 线程处理函数延迟到调用wait和get方法时候才执行,本质开始是没有创建子线程
int returnValue2(int num) {
	cout << "线程处理函数启动....." << endl;
	return num * 10;
}
void test04() {
	//MM mm;
	auto res = async(launch::async,returnValue2, 6); //默认参数
	//auto res = async(launch::deferred, returnValue2, 6);
	this_thread::sleep_for(1s); //延时1s
	cout << "---------get前-----------" << endl;
	cout << res.get() << endl;
	//cout << res.get() << endl;  //注 res只能被get()一次
	cout << "---------get后-----------" << endl;
}
int main() {

	test04();
	return 0;
}

使用launch::async参数结果, 创建线程并且执行线程处理函数 

使用launch::deferred参数结果, 线程处理函数延迟到调用wait和get方法时候才执行,本质开始是没有创建子线程

 

 注:  async的返回值 res 只能被 get() 一次

 

2. 使用类模板 packaged_task 打包线程处理函数

2.1 使用步骤

  1. 使用thread创建线程,然后通过类模板(packaged_task)包装处理带返回值的线程处理函数
  2. 通过packaged_task的对象调用get_future获取future对象,再通过get()方法得到子线程处理函数的返回值

2.2 普通函数的打包

#include <iostream>
#include <thread>
#include <future>
using namespace std;
 
int returnValue() {
	return 666;
}
//3.1 普通函数的打包
void test05() {
	packaged_task<int(void)> taskOne(returnValue);
	thread t1(ref(taskOne));
	t1.join();
	cout << taskOne.get_future().get() << endl;
}
 
int main() {

	test05();
	return 0;
}

2.3 带参数的普通函数的打包

#include <iostream>
#include <thread>
#include <future>
using namespace std;
 
int returnValue2(int num) {
	cout << "线程处理函数启动....." << endl;
	return num * 10;
}
//3.2 带参数普通函数打包
void test06() {
	packaged_task<int(int)> taskOne(bind(returnValue2,placeholders::_1));
	thread t1(ref(taskOne), 10);
	t1.join();
	cout << taskOne.get_future().get() << endl;
}
 
int main() {

	test06();
	return 0;
}

 

2.4 类的成员函数的打包

#include <iostream>
#include <thread>
#include <future>
using namespace std;

class MM {
public:
	int mmThreadFunc(int num) {
		cout << "子线程id: " << this_thread::get_id() << endl;
		num *= 10;
		chrono::microseconds duration(1000); //1000微秒
		this_thread::sleep_for(duration);
		return num;
	}
};

//3.2 类的成员函数的打包
void test07() {
	MM mm;
	packaged_task<int(int)> taskOne(bind(&MM::mmThreadFunc, &mm, placeholders::_1));
	thread t1(ref(taskOne), 5);
	t1.join();
	cout << taskOne.get_future().get() << endl;
}

int main() {

	test07();
	return 0;
}

 

2.5 Lambda表达式的打包

#include <iostream>
#include <thread>
#include <future>
using namespace std;
 
//3.3 Lambda表达式的打包
void test08() {
	packaged_task<int(int)> taskOne([](int num) {
		cout << "Lambda表达式线程id: " << this_thread::get_id() << endl;
		num *= 5;
		return num;
	});
	thread t1(ref(taskOne), 5);
	t1.join();
	cout << taskOne.get_future().get() << endl;
}
 
int main() {
 
	test08();
 
	return 0;
}

 

3. 使用类模板 promise 获取线程处理函数返回值

3.1 使用步骤

  1. 通过promise类模板构建对象,通过调用set_value 存储函数需要返回的值
  2. 通过get_future获取future对象,再通过get()方法获取线程处理函数的返回值

 

3.2 基本数据类型作为返回值返回

#include <iostream>
#include <thread>
#include <future>
using namespace std;
 
void promiseThread(promise<int>& temp, int data) {
	cout << "promise id: " << this_thread::get_id() << endl;
	data *= 10;
	temp.set_value(data);
}
void test09() {
	promise<int> temp;
	thread t1(promiseThread, ref(temp), 66);
	t1.join();
	cout << "promise value: " << temp.get_future().get() << endl;
}
 
int main() {
 
	test09();
 
	return 0;
}

#include <iostream>
#include <thread>
#include <future>
using namespace std;
 
//方式2
void promsieThread2(future<int>& temp) {
	cout << "promise id: " << this_thread::get_id() << endl;
	cout << "子线程: " << temp.get() << endl;
}
void test10() {
	promise<int> temp;
	temp.set_value(666);
	auto num = temp.get_future();
	thread t1(promsieThread2, ref(num));
	t1.join();
}
 
int main() {
 
	test10();
 
	return 0;
}

 

3.3 结构体类型作为返回值返回

#include <iostream>
#include <thread>
#include <future>
using namespace std;
 
//结构体类型参数传递
struct Person {
	int age;
	string name;
	friend ostream& operator<<(ostream& out, Person& person);
};
// << 运算符重载
ostream& operator<<(ostream& out, Person& person) {
	out << person.age << "\t" << person.name << endl;
	return out;
}
void promiseThread3(promise<Person>& temp, Person data) {
	cout << "promise id: " << this_thread::get_id() << endl;
	data.age = 100;
	data.name = "张三";
	temp.set_value(data);
}
void test11() {
	promise<Person> temp;
	Person person = { 18,"貂蝉" };
	thread t1(promiseThread3, ref(temp), person);
	t1.join();
	person = temp.get_future().get();
	cout << person << endl;
}
 
int main() {
 
	test11();
 
	return 0;
}

 

3.4 类中带返回值的普通函数作为线程处理函数

#include <iostream>
#include <thread>
#include <future>
using namespace std;
 
//类中带返回值普通函数充当线程处理函数
class MM2 {
public:
	void mmThreadFunc(promise<int>& temp, int num) {
		cout << "子线程id: " << this_thread::get_id() << endl;
		chrono::microseconds duration(1000); //1000微秒
		this_thread::sleep_for(duration);
		temp.set_value(num * 100);
	}
};
void test12() {
	promise<int> temp;
	MM2 mm;
	thread t1(&MM2::mmThreadFunc, &mm,ref(temp), 10);
	t1.join();
	cout << temp.get_future().get() << endl;
}
 
int main() {
 
	test12();
 
	return 0;
}

 

 

————————————————
版权声明:本文为CSDN博主「石小浪♪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
 
posted @ 2023-10-11 16:58  [BORUTO]  阅读(286)  评论(0编辑  收藏  举报