//(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; }