2017-03-01 34 views
5

它是否安全,如std::mutexstd::promise<T>mutable,還是取決於T?如:是std :: promise <T>線程安全嗎?

using Data = std::tuple<bool, int, int>; 

struct X { 

    std::future<Data> prepare() const { 
     return m_promise.get_future(); 
    } 

    void asyncHandler(int a, int b) const { 
     m_promise.set_value({true, a, b}); 
    } 

    void cancel() const { 
     m_promise.set_value({false, 0, 0}); 
    } 

    mutable std::promise<Data> m_promise; // Is this safe? 
}; 


void performAsyncOp(const X& x) { 
    std::future<Data> fut = x.prepare(); 
    dispatch(x); 
    std::future_status result = fut.wait_for(std::chrono::milliseconds(150)); 
    if (result == std::future_status::timeout) { 
     x.cancel(); 
    } 

    handleResult(fut.get()); 
} 
+0

事實證明,由於期貨不能重置,這種模式無論如何都被打破了。我以爲future.get()會重置它,但它不會。我很努力地看到所有這些承諾/未來的東西。 – James

回答

4

讓我們在API的詳細研究:

// retrieving the result 
future<R> get_future(); 

// setting the result 
void set_value(see below); 
void set_exception(exception_ptr p); 

// setting the result with deferred notification 
void set_value_at_thread_exit(see below); 
void set_exception_at_thread_exit(exception_ptr p); 

的方法都沒有被標記const,所以我們不能推斷出從眼前這個常量性的任何知識。然而,該標準強制以下方法(c.f. 33.6.6.2):set_­valueset_­exception,set_­value_­at_­thread_­exitset_­exception_­at_­thread_­exit的線程安全性。

這留下get_future關於線程安全的未指定。但是,如果調用多次,則get_future會引發異常,c.f. 33.6.6.14.1。所以從多個線程調用get_future從實際角度來看並不合理。

當我看到時,無法同時撥打get_futureset方法和get_future(無論它是否會拋出),無法保證線程安全。