栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

写在前面:

        又是学C扎扎的一天,C扎扎学起来果然扎手。如果你能坚持看到文章最后,你会发现,好吧有可能你啥也发现不了,因为后面什么也没有~~~

目录

1. 使用 async 函数创建线程

1.1 使用步骤

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

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

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

1.5 async的其它两个参数

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

2.1 使用步骤

2.2 普通函数的打包

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

2.4 类的成员函数的打包

2.5 Lambda表达式的打包

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

3.1 使用步骤

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

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

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


1. 使用 async 函数创建线程

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

1.2 基本数据类型作为返回值
#include 
#include 
#include 
using namespace std;

//1.1 普通类型返回值
int returnValue() {
	return 666;
}
void test01() {
	future res = async(returnValue);
	cout << res.get() << endl;
}

int main() {
    system("color F0");
	test01();
	return 0;
}

1.3 结构体类型数据作为返回值
#include 
#include 
#include 
#include 
#include 
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 res = async(returnPerson);
	Person person = res.get();
	cout << person << endl;
}
int main() {
    system("color F0");
	test02();
	return 0;
}

1.4 带返回值的类的成员函数作为线程处理函数
#include 
#include 
#include 
#include 
#include 
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 res = async(&MM::mmThreadFunc, &mm, 5);
	cout << res.get() << endl;
}
int main() {
    system("color F0");
	test03();
	return 0;
}

1.5 async的其它两个参数
#include 
#include 
#include 
#include 
#include 
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() {
    system("color F0");
	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 
#include 
#include 
using namespace std;

int returnValue() {
	return 666;
}
//3.1 普通函数的打包
void test05() {
	packaged_task taskOne(returnValue);
	thread t1(ref(taskOne));
	t1.join();
	cout << taskOne.get_future().get() << endl;
}

int main() {
    system("color F0");
	test05();
	return 0;
}

2.3 带参数的普通函数的打包
#include 
#include 
#include 
using namespace std;

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

int main() {
    system("color F0");
	test06();
	return 0;
}

2.4 类的成员函数的打包
#include 
#include 
#include 
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 taskOne(bind(&MM::mmThreadFunc, &mm, placeholders::_1));
	thread t1(ref(taskOne), 5);
	t1.join();
	cout << taskOne.get_future().get() << endl;
}

int main() {
    system("color F0");
	test07();
	return 0;
}

2.5 Lambda表达式的打包
#include 
#include 
#include 
using namespace std;

//3.3 Lambda表达式的打包
void test08() {
	packaged_task 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() {

	system("color F0");
	test08();

	return 0;
}

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

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

3.2  基本数据类型作为返回值返回
#include 
#include 
#include 
using namespace std;

void promiseThread(promise& temp, int data) {
	cout << "promise id: " << this_thread::get_id() << endl;
	data *= 10;
	temp.set_value(data);
}
void test09() {
	promise temp;
	thread t1(promiseThread, ref(temp), 66);
	t1.join();
	cout << "promise value: " << temp.get_future().get() << endl;
}

int main() {

	system("color F0");
	test09();

	return 0;
}

#include 
#include 
#include 
using namespace std;

//方式2
void promsieThread2(future& temp) {
	cout << "promise id: " << this_thread::get_id() << endl;
	cout << "子线程: " << temp.get() << endl;
}
void test10() {
	promise temp;
	temp.set_value(666);
	auto num = temp.get_future();
	thread t1(promsieThread2, ref(num));
	t1.join();
}

int main() {

	system("color F0");
	test10();

	return 0;
}

3.3 结构体类型作为返回值返回
#include 
#include 
#include 
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& temp, Person data) {
	cout << "promise id: " << this_thread::get_id() << endl;
	data.age = 100;
	data.name = "张三";
	temp.set_value(data);
}
void test11() {
	promise temp;
	Person person = { 18,"貂蝉" };
	thread t1(promiseThread3, ref(temp), person);
	t1.join();
	person = temp.get_future().get();
	cout << person << endl;
}

int main() {

	system("color F0");
	test11();

	return 0;
}

3.4 类中带返回值的普通函数作为线程处理函数
#include 
#include 
#include 
using namespace std;

//类中带返回值普通函数充当线程处理函数
class MM2 {
public:
	void mmThreadFunc(promise& 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 temp;
	MM2 mm;
	thread t1(&MM2::mmThreadFunc, &mm,ref(temp), 10);
	t1.join();
	cout << temp.get_future().get() << endl;
}

int main() {

	system("color F0");
	test12();

	return 0;
}

有一种思念
即便使尽全身的力气
即便站在最忠诚的回音壁前

却依然无法
呼喊出一个人的名字
—―杜拉斯

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/925405.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号