future其他成員函式,shared_future、atomic
阿新 • • 發佈:2018-12-21
int mythread() { cout << "mythread() start" << " thread id = " << std::this_thread::get_id() << endl; std::this_thread::sleep_for(2s); cout << "mythread() end " << " thread id = " << std::this_thread::get_id() << endl; return 5; } int main() { cout << "main id = " << std::this_thread::get_id() << endl; //async 非同步,等全部執行緒執行完主函式才返回 //std::future<int> result = std::async(mythread); std::future<int> result = std::async(std::launch::deferred,mythread); /*cout << result.get() << endl;*/ //列舉型別 std::future_status status = result.wait_for(std::chrono::seconds(3)); if (status == std::future_status::timeout) { //超時表示執行緒還沒執行完; cout << " time out " << endl; } else if (status == std::future_status::ready) { //表示執行緒成功返回 cout << " ready " << endl; cout << result.get() << endl; } else if(status == std::future_status::deferred) { //如果async的第一個引數設定為 std::launch::def cout << "執行緒延遲執行" << endl; cout << result.get() << endl; } cout << "continue.... " << endl; return 0; }
std::shread_future:也是類模板,get()函式只是複製資料
int mythread() { cout << "mythread() start" << " thread id = " << std::this_thread::get_id() << endl; std::this_thread::sleep_for(2s); return 5; } void mythread2(std::shared_future<int> &temp) { cout<<"mythread2() start" << " thread id = " << std::this_thread::get_id() << endl; auto result = temp.get(); cout << "mythread2 result = " << result << endl; return; } int main() { cout << "main id = " << std::this_thread::get_id() << endl; std::packaged_task<int(void)> mypt(mythread); std::thread t1(std::ref(mypt)); t1.join(); //std::future<int> result = mypt.get_future(); ////std::shared_future<int> result_s(std::move(result)); //std::shared_future<int> result_s(result.share()); //shared_future的get()函式只是複製資料 shared_future<int>result_s(mypt.get_future()); std::thread t2(mythread2, std::ref(result_s)); t2.join(); cout << "continue.... " << endl; return 0; }
當兩個執行緒同時修改一個全域性變數時,可能會出錯
int g_mycount = 0; void mythread() { cout << "mythread() start" << " thread id = " << std::this_thread::get_id() << endl; for (int i = 0; i < 10000000; i++) { g_mycount++; } return; } int main() { cout << "main id = " << std::this_thread::get_id() << endl; thread mytobj1(mythread); thread mytobj2(mythread); mytobj1.join(); mytobj2.join(); cout << "g_mucount = " << g_mycount << endl; cout << "continue.... " << endl; return 0; }
atomic:針對++,–,+=,&=,|=,&=,|=,^=是支援的。其它的可能不支援。
std::atomic<int> g_mycount = 0;//封裝一個型別為int的物件
std::atomic<bool> g_ifend = false;//執行緒退出標記。防止讀寫亂套
void mythread()
{
while(g_ifend == false)
{
cout << "mythread() start" << " thread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(2s);
}
cout << "mythread() end" << " thread id = " << std::this_thread::get_id() << endl;
return;
}
int main()
{
//原子操作:不需要用到互斥量加鎖技術的多執行緒併發程式設計方式
//在多執行緒中,不會被打斷程式的執行片段,比互斥量效率上更勝一籌。
//互斥量的加鎖一般是針對一個程式碼段(幾行程式碼或者更多),而原子操作針對的是一個變數。
//std::atomic來代表原子操作,是個類模板。是用來封裝某個型別的值。
cout << "main id = " << std::this_thread::get_id() << endl;
thread mytobj1(mythread);
thread mytobj2(mythread);
std::this_thread::sleep_for(5s);
g_ifend = true;
mytobj1.join();
mytobj2.join();
cout << "continue.... " << endl;
return 0;
}
std::async引數詳述:用來建立一個非同步任務
std::launch::deferred 延遲呼叫,並且不建立新執行緒,並在.get()或.wait()呼叫時才執行執行緒函式
std::launch::async 強制建立一個執行緒
std::thread() 如果系統資源緊張,那麼可能建立執行緒就會失敗,那麼執行thread()時整個程式可能崩潰。
std::async() 一般叫 建立一個非同步任務
std::async 和 thread 不同: async有時候並不建立執行緒。
如果兩個引數一起呼叫(或不帶引數),那就由系統選擇。
系統如何決定是 建立新執行緒還是同步方式執行。
std::thread建立執行緒的方式,如果執行緒返回值,你想拿到這個值也不容易。
由於系統資源限制
1)如果用thread建立的執行緒太多,則可能建立失敗,系統報告異常,崩潰
2)如果用async,一般就不會報異常不會崩潰,因為如果系統資源緊張導致無法建立新執行緒的時候,
async這種不加額外引數的呼叫就不會建立新執行緒,而是後續誰呼叫了 .get()的執行緒中繼續執行。
async不確定性問題解決
不加引數的async呼叫 std::future<int>result = std::async(mythread);
使用wait_for 解決