写在前面:
又是学C扎扎的一天,C扎扎学起来果然扎手。如果你能坚持看到文章最后,你会发现,好吧有可能你啥也发现不了,因为后面什么也没有~~~
1. 使用 async 函数创建线程
1.1 使用步骤
- 使用async函数启动一个异步任务(创建线程,并且执行线程处理函数),返回future对象
- 通过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() {
system("color F0");
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() {
system("color F0");
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() {
system("color F0");
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() {
system("color F0");
test04();
return 0;
}
**使用launch::async参数结果, 创建线程并且执行线程处理函数**
**使用launch::deferred参数结果, 线程处理函数延迟到调用wait和get方法时候才执行,本质开始是没有创建子线程**
注: async的返回值 res 只能被 get() 一次
2. 使用类模板 packaged_task 打包线程处理函数
2.1 使用步骤
- 使用thread创建线程,然后通过类模板(packaged_task)包装处理带返回值的线程处理函数
- 通过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() {
system("color F0");
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() {
system("color F0");
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() {
system("color F0");
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() {
system("color F0");
test08();
return 0;
}
3. 使用类模板 promise 获取线程处理函数返回值
3.1 使用步骤
- 通过promise类模板构建对象,通过调用set_value 存储函数需要返回的值
- 通过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() {
system("color F0");
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() {
system("color F0");
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() {
system("color F0");
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() {
system("color F0");
test12();
return 0;
}
有一种思念
即便使尽全身的力气
即便站在最忠诚的回音壁前却依然无法
呼喊出一个人的名字
—―杜拉斯