C++多线程编程第九讲--async、future、packaged_task、promise

//(1)std::async、 std::future创建后台任务并返回值
// async是一个函数模板,用来启动一个异步任务,返回一个future类型的对象。用future
// 的get方法来获得线程的返回值。
// 异步任务:自动创建一个线程,并开始执行对应线程的入口函数。
#include<iostream>
#include<mutex>
#include<thread>
#include<future>

using namespace std;

int my_thread()
{
	cout << "my_thread start...  " << "thread id = " << this_thread::get_id() << endl;
	std::chrono::milliseconds duro(5000);
	std::this_thread::sleep_for(duro);
	cout << "my_thread end...  " << "thread id = " << this_thread::get_id() << endl;
	return 5;
}

int main()
{
	cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
	std::future<int> result = std::async(my_thread);
	cout << result.get() << endl;              //主线程会在get这里一致等到新的线程返回结果
	//cout << result.get() << endl;            //不能调用多次,调用多次会报异常
	//result.wait();  //等待新的线程执行结束,但并不会储存返回值。
	cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
	return 0;
}

#include<iostream>
#include<mutex>
#include<thread>
#include<future>

using namespace std;
class A
{
public:
	int my_thread(int mypar)
	{
		cout << "my_thread start...  " << "thread id = " << this_thread::get_id() << endl;
		std::chrono::milliseconds duro(5000);
		std::this_thread::sleep_for(duro);
		cout << "my_thread end...  " << "thread id = " << this_thread::get_id() << endl;
		return mypar;
	}
};



int main()
{
	A myobja;
	cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
	std::future<int> result = std::async(&A::my_thread, std::ref(myobja), 5);
	//主线程会在get这里一致等到新的线程返回结果,如果没有这一句的话
	//在主线程return的时候,会等待新的线程执行结束。
	cout << result.get() << endl;
	//cout << result.get() << endl;            //不能调用多次,调用多次会报异常
	//result.wait();  //等待新的线程执行结束,但并不会储存返回值。
	cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
	return 0;
}

// 可以额外向std::async()传递一个参数,参数类型是std::lunch类型(枚举)。
// std::launch::deferred  新线程执行时间延迟到调用wait或者get时才执行(创建)

#include<iostream>
#include<mutex>
#include<thread>
#include<future>

using namespace std;
class A
{
public:
	int my_thread(int mypar)
	{
		cout << "my_thread start...  " << "thread id = " << this_thread::get_id() << endl;
		std::chrono::milliseconds duro(5000);
		std::this_thread::sleep_for(duro);
		cout << "my_thread end...  " << "thread id = " << this_thread::get_id() << endl;
		return mypar;
	}
};



int main()
{
	A myobja;
	cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
	//新线程延迟到调用wait或者get的时候再启动,但使用std::launch::deferred这个参数
	//直接没有创建新的线程,在主线程中调用的入口函数。
	std::future<int> result = std::async(std::launch::deferred, &A::my_thread, std::ref(myobja), 5);
	//主线程会在get这里一致等到新的线程返回结果,如果没有这一句的话
	//在主线程return的时候,会等待新的线程执行结束。
	cout << result.get() << endl;                   //在主线程中执行。
	//cout << result.get() << endl;            //不能调用多次,调用多次会报异常
	//result.wait();  //等待新的线程执行结束,但并不会储存返回值。
	cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
	return 0;
}

// std::launch::async 在调用async这个函数的时候即开始创建新的线程,执行入口函数。默认async方法的第一个参数
//就是std::launch::async
// 
//(2)std::packaged_task   是个模板类,将各种可调用对象包装起来。

#include<iostream>
#include<mutex>
#include<thread>
#include<future>

using namespace std;

int my_thread(int mypar)
{
	cout << "my_thread start...  " << "thread id = " << this_thread::get_id() << endl;
	std::chrono::milliseconds duro(5000);
	std::this_thread::sleep_for(duro);
	cout << "my_thread end...  " << "thread id = " << this_thread::get_id() << endl;
	return mypar;
}

int main()
{
	cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;

	std::packaged_task<int(int)> mypt(my_thread);           //把函数my_thread包装起来
	std::thread t1(std::ref(mypt), 5);                      //用一个package_task对象作为线程的参数

	t1.join();

	std::future<int> result = mypt.get_future();

	cout << result.get() << endl;              //打印返回的结果

	cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
	return 0;
}
 
#include<iostream>
#include<mutex>
#include<thread>
#include<future>

using namespace std;

int main()
{
	cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;

	//包装lamda表达式
	std::packaged_task<int(int)> mypt([](int mypar)
		{
			cout << "my_thread start...  " << "thread id = " << this_thread::get_id() << endl;
			std::chrono::milliseconds duro(5000);
			std::this_thread::sleep_for(duro);
			cout << "my_thread end...  " << "thread id = " << this_thread::get_id() << endl;
			return mypar;
		}
	);

	std::thread t1(std::ref(mypt), 5);                      //用一个package_task对象作为线程的参数

	t1.join();

	std::future<int> result = mypt.get_future();

	cout << result.get() << endl;              //打印返回的结果

	cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
	return 0;
}

#include<iostream>
#include<mutex>
#include<thread>
#include<future>

using namespace std;

int main()
{
	cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;

	//包装lamda表达式
	std::packaged_task<int(int)> mypt([](int mypar)
		{
			cout << "my_thread start...  " << "thread id = " << this_thread::get_id() << endl;
			std::chrono::milliseconds duro(5000);
			std::this_thread::sleep_for(duro);
			cout << "my_thread end...  " << "thread id = " << this_thread::get_id() << endl;
			return mypar;
		}
	);

	mypt(5);            //不创建新的线程,直接调用也可以。

	std::future<int> result = mypt.get_future();

	cout << result.get() << endl;              //打印返回的结果

	cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
	return 0;
}

#include<iostream>
#include<mutex>
#include<thread>
#include<future>
#include<vector>

using namespace std;

vector<std::packaged_task<int(int)>> mytasks;

int main()
{
	cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;

	//包装lamda表达式
	std::packaged_task<int(int)> mypt([](int mypar)
		{
			cout << "my_thread start...  " << "thread id = " << this_thread::get_id() << endl;
			std::chrono::milliseconds duro(5000);
			std::this_thread::sleep_for(duro);
			cout << "my_thread end...  " << "thread id = " << this_thread::get_id() << endl;
			return mypar;
		}
	);

	mytasks.push_back(std::move(mypt));     //使用移动语义

	std::packaged_task<int(int)> mypt2;
	auto iter = mytasks.begin();
	mypt2 = std::move(*iter);

	mytasks.erase(iter);              //迭代器失效,后面不可以使用iter

	mypt2(123);
	std::future<int> result = mypt2.get_future();
	cout << result.get() << endl;


	cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
	return 0;
}

//(3)std::promise
// 我们可以在某个线程中给他赋值,在其他线程中把这个值取出来。
#include<iostream>
#include<mutex>
#include<thread>
#include<future>
#include<vector>
#include<memory>

using namespace std;

void my_thread(std::promise<int>& tmp, int calc)
{
	cout << "my_thread start..." << endl;
	cout << "my_thread id = " << std::this_thread::get_id() << endl;
	cout << calc << endl;
	std::chrono::milliseconds duro(5000);   //休眠5秒,模拟计算过程
	std::this_thread::sleep_for(duro);


	int result = calc;

	tmp.set_value(result);    //将结果保存到promise的对象中

	cout << "my_thread end..." << endl;
}

void my_thread2(std::future<int>& tmpf)
{
	cout << "my_thread2 start..." << endl;
	cout << "thread id = " << std::this_thread::get_id() << endl;
	cout << tmpf.get() << endl;   //获得另外一个线程传过来的值

	cout << "my_thread2 end..." << endl;
}

int main()
{
	cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
	
	std::promise<int> result;
	//std::thread t1(my_thread, result, 123);                 //错误
	std::thread t1(my_thread, std::ref(result), 123);         //使用ref来传递,不能直接赋值对象。
	auto fut = result.get_future();
	std::thread t2(my_thread2, std::ref(fut));

	t1.join();                                
	t2.join();

	cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
	return 0;
}

  

posted on 2021-10-21 23:12  xcxfury001  阅读(88)  评论(0)    收藏  举报

导航