請考慮以下示例。假設你有一個生產者和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關聯的未來是準備好的。這將簡化我的情況下的代碼(而不是將新的承諾傳遞給生產者線程)。如果你有更好的想法,請告訴我。
我的測試顯示它會工作... – Martin 2015-02-07 20:54:42