首页 > 编程语言 >C++ - 多线程之带返回值的线程处理函数

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

时间:2023-10-11 17:16:12浏览次数:39  
标签:多线程 cout int 线程 返回值 include 处理函数 之带

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版权协议,转载请附上原文出处链接及本声明。   原文链接:https://blog.csdn.net/ShiXiAoLaNga/article/details/124934703

标签:多线程,cout,int,线程,返回值,include,处理函数,之带
From: https://www.cnblogs.com/zhuchunlin/p/17757646.html

相关文章

  • C++ - 多线程之线程同步
    1.多线程的并发问题线程间为什么需要同步?直接来看一个例子:inta=0;voidfoo(){ for(inti=0;i<10000000;++i) { a+=1; }}intmain(){ clock_tstart,end; start=clock(); threadt1(foo); threadt2(foo); t1.join(); t2.join(); end=clock();......
  • libuv多线程简单应用示范
     #include<stdio.h>#include<uv.h>//声明回调函数voidasyncCallback(uv_async_t*handle);voidclose_cb();voidthread_func_1(void*arg);voidthread_func_2(void*arg);//定时器回调函数voidtimer_callback(uv_timer_t*handle){//定时器触发后执......
  • linux 多线程写
      pread 和 pwrite 函数是linux下C语言编程中非常好用的IO操作函数。它们属于系统调用,在2.1.60之后版本的linux下都可以使用,尤其适合用于多线程的应用中,它们允许多个线程操作同一个文件描述符,不会互相影响彼此的文件偏移(offset)。 pread和pwrite函数所需......
  • 多线程分批处理数据(控制服务器cpu,控制数据库cpu)
    packageip;importcom.google.common.collect.Lists;importlombok.extern.slf4j.Slf4j;importjava.util.List;importjava.util.concurrent.CountDownLatch;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;/***功能描述:总思路,根据业务......
  • 多线程使用场景三-异步调用
         ......
  • 多线程使用场景二(数据汇总)
       ......
  • python多线程
    importdatetimeimportthreadingfromtimeimportsleep#创建一个信号量,限制最多同时运行2个线程semaphore=threading.Semaphore(2)#创建一个线程锁threadLock=threading.Lock()defworker(i):withsemaphore:current_datetime=datetime.datet......
  • 多线程,线程同步(synchronized),并发问题
    多个线程同时操作一个对象,就会出现并发问题,所以需要线程同步,线程同步是一种等待机制。 线程同步的形成条件:队列+锁(锁就是例如上厕所,一个进去锁住避免其他进入。到下一个进去再锁住)线程同步来解决线程的不安全性弊端!: ......
  • 多线程,守护线程daemon
    简介: 下面例子:首先两个线程类实现Runnable接口 然后在主线程模拟一下上帝守护你 其中,setDaemon方法可以切换线程模式......
  • 多线程,线程优先级Priority
    线程优先级(Priority)用数字表示,范围从1~10,优先级越高,给的资源就多一点,被执行的可能就高一些  优先级默认为5 注意!!!要先设置优先级再启动线程!!! ......