2015-02-07 59 views
3

請考慮以下示例。假設你有一個生產者和N個消費者等待數據。您不僅要在數據準備就緒時通知消費者,而且還要由於某種原因(錯誤或中斷點)終止生產者。在後一種情況下,讀者也應該終止。在線程出口通知服務員

// Globals 
boost::shared_future<void> future; 
boost::condition_variable_any cv; 

// Producer 
auto producer = [&](){ 
    boost::this_thread::at_thread_exit([&cv]() { cv.notify_all(); }); 
    while (true) { 
      boost::this_thread::interruption_point(); // might throw 
      // ... 
      cv.notify_all(); 
    } 
}; 
boost::packaged_task<void> pkg{producer}; 
future = pkg.get_future(); 
thread = boost::thread{std::move(pkg)}; // start 

// Reader 
while (true) { 
     // ... 
     // will the future be ready after the producer has been interrupted? 
     cv.wait(lock_, [&ready, &future]() { return ready || future.is_ready(); }); 
     if (future.is_ready()) { 
      future.get(); // throw, whatever has been thrown by the producer 
      return; 
     } 
     // consume, etc... 
} 

以上保證有效嗎?我想避免引入一個布爾標誌或 - 更好 - 另一個新的承諾/未來對來通知並讓讀者知道爲什麼生產者已經退出。

基本上我不確定當與boost::this_thread::at_thread_exit註冊的函數通知讀者時,是否可以認爲與packaged_task關聯的未來是準備好的。這將簡化我的情況下的代碼(而不是將新的承諾傳遞給生產者線程)。如果你有更好的想法,請告訴我。

+0

我的測試顯示它會工作... – Martin 2015-02-07 20:54:42

回答

1

是的這將工作。

特別

基本上我不知道如果與packaged_task相關聯的未來可以被認爲是準備當讀者通過與boost::this_thread::at_thread_exit

他們可以註冊的功能通知。 packaged_task是線程函數。當thread_proxy implementation from Boost Thread執行tls_destructor(其中包括at_thread_exit鉤子)時,packaged_task已經返回並且承諾已經實現 - >共享未來已準備就緒。