C++多线程编程第十讲--future其他成员函数、shared_future、atomic
//(1)std::future的其他成员函数
#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);
std::future_status status = result.wait_for(std::chrono::milliseconds(6000)); //等待
if (status == std::future_status::timeout)
{
//超时表示等待的线程还没有执行结束
cout << "overtime..." << endl;
}
else if (status == std::future_status::ready)
{
cout << "ready..." << endl;
}
else if (status == std::future_status::deferred) //线程还没开始执行
{
cout << "deferred..." << endl; //对应async中第一个参数中的std::launch::deferred
}
cout << result.get() << endl; //主线程会在get这里一致等到新的线程返回结果
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
//(2)std::shared_future
// 是一个类模板,他的get函数就不是转移了,而是复制。
//
// 如以下程序,只能在线程2中调用get,如果还有其他线程想要线程1返回的结果再次调用get的时候
// 程序就会报错
#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;
}
void my_thread2(std::future<int>& fut)
{
cout << "my_thread2 start..." << "thread id = " << this_thread::get_id() << endl;
//程序运行到这里,即便线程1还没有执行结束,调用get也会等待线程1返回结果再运行
cout << "fut.get() = " << fut.get() << endl; //打印返回的结果,get函数设计是一个移动语义,所以不能调用两次。
cout << "my_thread2 end..." << "thread id = " << this_thread::get_id() << endl;
}
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对象作为线程的参数
std::future<int> result = mypt.get_future();
//std::shared_future<int> s_fut(std::move(result)); //使用右值
std::thread t2(my_thread2, std::ref(result)); //future对象不能拷贝,所以只能以std::ref的方式进行传递
t2.join();
t1.join();
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
// 则使用shared_future避免以上的情况
#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;
}
void my_thread2(std::shared_future<int>& s_fut)
{
cout << "my_thread2 start..." << "thread id = " << this_thread::get_id() << endl;
//程序运行到这里,即便线程1还没有执行结束,调用get也会等待线程1返回结果再运行
cout << "fut.get() = " << s_fut.get() << endl; //get只是复制,可以调用多次
cout << "my_thread2 end..." << "thread id = " << this_thread::get_id() << endl;
}
void my_thread3(std::shared_future<int>& s_fut)
{
cout << "my_thread3 start..." << "thread id = " << this_thread::get_id() << endl;
//程序运行到这里,即便线程1还没有执行结束,调用get也会等待线程1返回结果再运行
cout << "fut.get() = " << s_fut.get() << endl; //get只是复制,可以调用多次
cout << "my_thread3 end..." << "thread id = " << this_thread::get_id() << endl;
}
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对象作为线程的参数
std::future<int> result = mypt.get_future();
//bool value = result.valid(); //可以用来判断result中是否有有效值
std::shared_future<int> s_fut(std::move(result)); //使用右值
//std::shared_future<int> s_fut(result.share()); //使用右值,两种写法都可以
std::thread t2(my_thread2, std::ref(s_fut)); //future对象不能拷贝,所以只能以std::ref的方式进行传递
std::thread t3(my_thread3, std::ref(s_fut)); //future对象不能拷贝,所以只能以std::ref的方式进行传递
t2.join();
t1.join();
t3.join();
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 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;
}
void my_thread2(std::shared_future<int>& s_fut)
{
cout << "my_thread2 start..." << "thread id = " << this_thread::get_id() << endl;
//程序运行到这里,即便线程1还没有执行结束,调用get也会等待线程1返回结果再运行
cout << "fut.get() = " << s_fut.get() << endl; //get只是复制,可以调用多次
cout << "my_thread2 end..." << "thread id = " << this_thread::get_id() << endl;
}
void my_thread3(std::shared_future<int>& s_fut)
{
cout << "my_thread3 start..." << "thread id = " << this_thread::get_id() << endl;
//程序运行到这里,即便线程1还没有执行结束,调用get也会等待线程1返回结果再运行
cout << "fut.get() = " << s_fut.get() << endl; //get只是复制,可以调用多次
cout << "my_thread3 end..." << "thread id = " << this_thread::get_id() << endl;
}
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对象作为线程的参数
//bool value = result.valid(); //可以用来判断result中是否有有效值
std::shared_future<int> s_fut(mypt.get_future()); //使用右值
//std::shared_future<int> s_fut(result.share()); //使用右值,两种写法都可以
std::thread t2(my_thread2, std::ref(s_fut)); //future对象不能拷贝,所以只能以std::ref的方式进行传递
std::thread t3(my_thread3, std::ref(s_fut)); //future对象不能拷贝,所以只能以std::ref的方式进行传递
t2.join();
t1.join();
t3.join();
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
//(3)原子操作std::atomic
//(3.1)原子操作概念引出范例
#include<iostream>
#include<mutex>
#include<thread>
#include<future>
using namespace std;
int g_mycount = 0;
mutex g_my_mutex;
void my_thread()
{
int i = 0;
for (; i < 1000000; ++i)
{
g_my_mutex.lock(); //防止++的执行被打断
g_mycount++;
g_my_mutex.unlock();
}
}
int main()
{
cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
thread mythread(my_thread);
thread mythread2(my_thread);
mythread.join();
mythread2.join();
cout << g_mycount << endl;
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
// 但是以上的程序效率太低,原子操作也会有相同的作用。互斥量的加锁针对的是一个代码段,而原子操作
// 针对的是一个变量。原子操作用于统计功能等。
//(3.2)基本的std::atomic用法范例
#include<iostream>
#include<mutex>
#include<thread>
#include<future>
using namespace std;
//int g_mycount = 0;
std::atomic<int> g_mycount = 0; //具备原子操作的整型值
void my_thread()
{
int i = 0;
for (; i < 1000000; ++i)
{
g_mycount++;
}
}
int main()
{
cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
thread mythread(my_thread);
thread mythread2(my_thread);
mythread.join();
mythread2.join();
cout << g_mycount << 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 g_mycount = 0;
std::atomic<bool> g_ifend = false;
void my_thread()
{
std::chrono::milliseconds dura(1000); //
while (g_ifend == false)
{
cout << "my_thread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(dura);
}
}
int main()
{
cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
thread mythread(my_thread);
thread mythread2(my_thread);
std::chrono::milliseconds dura(5000); //
std::this_thread::sleep_for(dura);
g_ifend = true;
mythread.join();
mythread2.join();
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
posted on 2021-10-26 08:25 xcxfury001 阅读(58) 评论(0) 收藏 举报
浙公网安备 33010602011771号