C++11多線程——之std::promise學習

一  <future>頭文件簡介

1 Classes

std::future

std::future_error

std::packaged_task

std::promise

std::shared_future

2 Functions

std::async

std::future_category

二 std::promise類

1 std::promise class statement

Template <class T> promise;
Template <classR&> promise<R&> // specialization : T is a reference type(R&)
Template <> promise<void>;//specialization : T is void

2 introduce std::promise

Promise對象可保存T類型的值,該值可被future對象讀取(可能在另一個線程中),這是promise提供的同步的一種手段。在構造promise時,promise對象可以與共享狀態關聯起來,這個共享狀態可以存儲一個T類型或者一個由std::exception派生出的類的值,並可以通過get_future來獲取與promise對象關聯的對象,調用該函數之後,兩個對象共享相同的共享狀態(shared state)

Promise對象是異步provider,它可以在某一時刻設置共享狀態的值

Future對象可以返回共享狀態的值,或者在必要的情況下阻塞調用者並等待共享狀態標識變爲ready,然後才能獲取共享狀態的值。

There is a simple example to explain above relations:

#include <iostream>//std::cout
#include <future>//std::promisestd::future
#include <thread>//std::thread
#include <functional>//std::ref
 
void printInt(std::future<int>&fut)
{
        int x = fut.get();
        std::cout << "value ="<< x << "\n";
}
 
int main(int argc, _TCHAR* argv[])
{
        std::promise<int> prom;
        std::future<int>fut =prom.get_future();//將prom與fut關聯
        std::thread th(printInt,std::ref(fut));//新建線程,執行printInt函數
 
        prom.set_value(10);//設置共享狀態的值
        th.join();
        return 0;
}

 

         3 std::promise constructor

Default(1)                  promise()
With allocator(2)           template<class Alloc>promise(allocator_arg_t,aa,const Alloc&alloc);
Copy[delete](3)             promise(constpromise&) = delete;
Move(4)                     promise(constpromise&&x)noexcept;

(1)  Default constructor

初始化一個空的共享狀態

(2)  Constructor with allocator

與默認構造函數類似,但是使用自定義的分配器分配共享狀態

(3)  Copy constructor [delete]

(4)    Move constructor

 There is aexample to explain the std::promise constructor:

//promise constructors
#include <iostream>       // std::cout
#include <functional>     // std::ref
#include <memory>         // std::allocator,std::allocator_arg
#include <thread>         // std::thread
#include <future>         // std::promise, std::future
 
void print_int(std::future<int>& fut) {
        int x = fut.get();
        std::cout << "value: " << x << '\n';
}
 
int main()
{
        std::promise<int> foo;
        std::promise<int> bar = std::promise<int>(std::allocator_arg,std::allocator<int>());
 
        std::future<int> fut =bar.get_future();
 
        std::thread th(print_int,std::ref(fut));
 
        bar.set_value(20);
 
        th.join();
        return 0;
}


4 std::promise member functions

         4.1std::promise::get_future

改函數返回一個與promise共享狀態相關聯的future對象。返回的future對象可以訪問由promise對象設置在共享狀態的值或某異常對象。且只能從promise對象的共享狀態獲取一個future對象。調用該函數之後,promise對象通常會在某個時間點設置好(一個值或者一個異常對象),如果不設置值或異常,promise在析構時會自動的設置一個future_error異常來設置自身的準備狀態。

         4.2 std::promise::set_value

Generictemplate            void set_value(constT& val)
                           void set_value(T&& val)
specializations            void promise<R&>::set_value(R&val)
                           void promise<void>::set_value(void)

設置共享狀態的值,此後promise共享狀態標識變爲ready

         4.3std::promise::set_exception

爲promise設置異常,此後promise的共享狀態標識變爲ready

                  

                   Example:

//promise::set_exception
#include <iostream>       // std::cin, std::cout,std::ios
#include <functional>     // std::ref
#include <thread>         // std::thread
#include <future>         // std::promise, std::future
#include <exception>      // std::exception, std::current_exception
 
void get_int(std::promise<int>& prom) {
        int x;
        std::cout << "Please, enteran integer value: ";
        std::cin.exceptions(std::ios::failbit);   // throw on failbit
        try {
                  std::cin >> x;                           // sets failbit ifinput is not int
                  prom.set_value(x);
        }
        catch (std::exception&) {
                  prom.set_exception(std::current_exception());
        }
}
 
void print_int(std::future<int>& fut) {
        try {
                  int x = fut.get();
                  std::cout << "value: " << x << '\n';
        }
        catch (std::exception& e) {
                  std::cout << "[exceptioncaught: "<< e.what() << "]\n";
        }
}
 
int main()
{
        std::promise<int> prom;
        std::future<int> fut =prom.get_future();
 
        std::thread th1(print_int,std::ref(fut));
        std::thread th2(get_int,std::ref(prom));
 
        th1.join();
        th2.join();
        return 0;
}


         4.4 std::promise::set_value_at_thread_exit

設置共享狀態的值,但不是立刻設置,而是在線程退出時,promise自動設置共享狀態的值。若某future對象與promise對象相關聯,並且該future對象正在調用get,則調用get的線程會被阻塞,當線程退出時,調用future::get的線程自動解除阻塞,同時返回promise::set_value_at_thread_exit所設置的值

注意:該線程以設置promise的值,如果在線程結束之後有其他修改共享狀態值得操作,會拋出future_error(promise_already_satisfied)異常

 

         4.5 std::promise::operator = (移動賦值)

//promise::operator=
#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <future>         // std::promise, std::future
 
std::promise<int> prom;
 
voidprint_global_promise() {
        std::future<int> fut =prom.get_future();
        int x = fut.get();
        std::cout << "value: " << x << '\n';
}
 
int main()
{
        std::threadth1(print_global_promise);
        prom.set_value(10);
        th1.join();
 
        prom = std::promise<int>();    // reset, by move-assigning a new promise
 
        std::threadth2(print_global_promise);
        prom.set_value(20);
        th2.join();
 
        return 0;
}


         4.6 std::promise::swap(non-member-overloads)

                   交換兩個promise的共享狀態

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章