當兩個線程間須要傳遞數據時,能夠使用promise與future來實現。ios
線程A經過promise.setvalue來設置數據,線程B經過promise的get_future獲取future後,從future中獲取數據。future寫用法與前面博文用法一致。promise
【一】設置數據與獲取數據spa
#include<iostream> #include<thread> #include<mutex> #include<condition_variable> #include<future> #include<chrono> using namespace std; void f(future<int> &fu) { cout << fu.get() << endl; } int main(int argc, int * argv[]) { promise<int> pro; future<int> fu = pro.get_future(); thread t1(f, std::ref(fu)); pro.set_value(10); t1.join(); cout << "main" << endl; system("pause"); }
結果以下:線程
【二】只get,不set設計
#include<iostream> #include<thread> #include<mutex> #include<condition_variable> #include<future> #include<chrono> using namespace std; void f(future<int> &fu) { cout << fu.get() << endl; } int main(int argc, int * argv[]) { promise<int> pro; future<int> fu = pro.get_future(); thread t1(f, std::ref(fu)); //pro.set_value(10); t1.join(); cout << "main" << endl; system("pause"); }
子線程會一直阻塞在fu.get上code
【三】set一次,get屢次get
#include<iostream> #include<thread> #include<mutex> #include<condition_variable> #include<future> #include<chrono> using namespace std; void f(future<int> &fu) { cout << fu.get() << endl; cout << fu.get() << endl; } int main(int argc, int * argv[]) { promise<int> pro; future<int> fu = pro.get_future(); thread t1(f, std::ref(fu)); pro.set_value(10); t1.join(); cout << "main" << endl; system("pause"); }
程序會運行失敗。當使用promise set_value時,future便處於ready狀態,能夠get到值,第二次get時,因爲future被get了一次,不能夠被get第二次,因此第二次get會失敗。future設計上,就是隻能get一次it
同時,promise只能被set一次,不能被set第二次。io
以下程序會崩潰class
int main(int argc, int * argv[]) { promise<int> pro; future<int> fu = pro.get_future(); //thread t1(f, std::ref(fu)); pro.set_value(10); pro.set_value(10); //t1.join(); cout << "main" << endl; system("pause"); }
若是隻set,而沒有get,是沒有問題的
int main(int argc, int * argv[]) { promise<int> pro; future<int> fu = pro.get_future(); //thread t1(f, std::ref(fu)); pro.set_value(10); //pro.set_value(10); //t1.join(); cout << "main" << endl; system("pause"); }
【四】一個線程set,兩個線程get
#include<iostream> #include<thread> #include<mutex> #include<condition_variable> #include<future> #include<chrono> using namespace std; void f(future<int> &fu) { cout << "f"<<fu.get() << endl; //cout << fu.get() << endl; } void f2(future<int> &fu) { cout << "f2"<<fu.get() << endl; //cout << fu.get() << endl; } int main(int argc, int * argv[]) { promise<int> pro; future<int> fu = pro.get_future(); thread t1(f, std::ref(fu)); thread t2(f, std::ref(fu)); pro.set_value(10); //pro.set_value(10); t1.join(); t2.join(); cout << "main" << endl; system("pause"); }
該程序會崩潰。
【五】注意點。join的位置應該在set以前,不然子線程會因爲沒有數據而一直等待
#include<iostream> #include<thread> #include<mutex> #include<condition_variable> #include<future> #include<chrono> using namespace std; void f(future<int> &fu) { cout << "f"<<fu.get() << endl; } int main(int argc, int * argv[]) { promise<int> pro; future<int> fu = pro.get_future(); thread t1(f, std::ref(fu)); t1.join(); pro.set_value(10); // set在join以後,子線程會一直等待,而主線程也一直在等待子線程運行結束後纔會set,因此造成死循環。 cout << "main" << endl; system("pause"); }
總結:使用future與promise進行線程間數據共享,其實是一種一次性消費,僅支持一對一,並且是一次性消費,不能再使用第二次。