C++多线程学习(四、带返回值的线程处理函数)

目录

简单流程

第一种:

1.带返回值的普通函数充当线程处理函数

2.以类中的成员函数作为线程处理函数【有输入值和返回值】

3.async和deferred的使用

第二种:

1.打包普通函数

2.打包类中的成员函数

3.打包lambda表达式

第三种:

一:正常函数

二:别的子线程获取这个子线程的promise内的数据


简单流程

第一种:

1.采用async:启动一个异步的任务,创建线程并执行线程处理函数,返回值future对象。

2.通过future对象中的get()方法获取线程函数的返回值

1.带返回值的普通函数充当线程处理函数

#include <thread>
#include <iostream>
#include <future>
using namespace std;
int ReturnValue()
{
	return 100;
}

int main()
{
	future<int> t = async(ReturnValue);
	cout << t.get() << endl;
	return 0;
}


2.以类中的成员函数作为线程处理函数【有输入值和返回值】

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

class DFTX
{
public:
	int ReturnClassOne(int num)
	{
		cout << "当前线程id:" << this_thread::get_id()<<endl;
		num *= 2;
		this_thread::sleep_for(chrono::milliseconds(5000));//延迟一下5000毫秒
		return num;
	}
};

int main()
{
	DFTX t1;
	auto temp = async(&DFTX::ReturnClassOne, &t1, 10);//DFTX类的成员函数ReturnClassOne,对象是t1,输入10,返回temp;
	cout << temp.get() << endl;
	return 0;
}


3.async和deferred的使用

async:创建线程,执行线程处理函数

deferred:线程处理函数延迟到我们调用wait和get方法时候才会执行,本质是没有创建子线程

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

class DFTX
{
public:
	int ReturnClassOne(int num)
	{
		cout << "当前线程id:" << this_thread::get_id()<<endl;
		num *= 2;
		this_thread::sleep_for(chrono::milliseconds(5000));//延迟一下5000毫秒
		return num;
	}
};

int main()
{
	DFTX t1;
	auto temp = async(launch::async,&DFTX::ReturnClassOne, &t1, 10);//launch::async 创建并调用
	cout << temp.get() << endl;
	auto temp2 = async(launch::deferred, &DFTX::ReturnClassOne, &t1, 50);//在这里并没有发生调用
	cout << temp2.get() << endl;//这里才开始调用线程

	return 0;
}


第二种:

用thread处理带返回值的线程处理函数

1.通过类模板packaged_task包装线程处理函数

2.通过packaged_task的对象调用get_future获取future对象,再通过get()方法得到子线程处理函数的返回值

1.打包普通函数

#include <thread>
#include <iostream>
#include <future>
#include <chrono>
using namespace std;
int PPAP()
{
	return 100;
}
void packThread()
{
	packaged_task<int(void)> PackOne(PPAP);//<int(void)>是指返回值为int的函数
	thread t1(ref(PackOne));//用ref做一个转换
	t1.join();
	cout << PackOne.get_future().get() << endl;//获取值
}

int main()
{
	packThread();

	return 0;
}


2.打包类中的成员函数

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

class DFTX
{
public:
	int papap(int num)
	{
		num *= 2;
		return num;
	}
};
void packThread()
{
	DFTX p1;
	packaged_task<int(int)> pack1(bind(&DFTX::papap,&p1,placeholders::_1));
	thread t1(ref(pack1),20);
	t1.join();
	cout << pack1.get_future().get() << endl;

}

int main()
{
	packThread();

	return 0;
}


3.打包lambda表达式

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

class DFTX
{
public:
	int papap(int num)
	{
		num *= 2;
		return num;
	}
};
void packThread()
{
	packaged_task<int(int)> t1([](int num)
	{
			num *= 10;
			return num;
	});
	thread p1(ref(t1),10);
	p1.join();
	cout << t1.get_future().get() << endl;
}

int main()
{
	packThread();

	return 0;
}


第三种:

通过promise获取线程函数“返回值”。

1:通过promise类模板构建对象,通过调用set_value是存储函数需要返回的值

2:通过get_future获取future对象,再通过get()方法获取线程处理函数中值【一旦通过get_future获取到future对象后,就不能再次调用get_future函数来获取新的future对象(除非你创建一个新的)】

一:正常函数

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

void PromiseTest(promise<int>& SaveData, int data)
{
	data *= 3;//计算出值
	SaveData.set_value(data);//存储到SaveData里面
}

int main()
{
	promise<int> p1;
	thread t1(PromiseTest, ref(p1),15);
	t1.join();
	cout << p1.get_future().get() << endl;
	return 0;
}


二:别的子线程获取这个子线程的promise内的数据

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

void PromiseTest(promise<int>& SaveData, int data)
{
	data *= 3;//计算出值
	SaveData.set_value(data);//存储到SaveData里面
}
void otherGet(future<int>& SaveData)
{
	auto result = SaveData.get();
	cout << result<<endl;
}
int main()
{
	promise<int> p1;
	thread t1(PromiseTest, ref(p1),15);
	t1.join();
	int nnn = p1.get_future().get();
	cout << nnn << endl;//get只能使用一次,否则出错

	promise<int> temp;
	temp.set_value(nnn);
	auto num = temp.get_future();
	thread t2(otherGet, ref(num));
	t2.join();

	return 0;
}


猜你喜欢

转载自blog.csdn.net/q244645787/article/details/131543170