1 #include 2 #include 3 #include 4 #include 5 #include 6 7 std::mutex coutMutex; 8 9 long double getDifference(const std::chrono::steady_clock::time_point& tp1,const std::chrono::steady_clock::time_point& tp2){ 0 auto diff= tp2- tp1; 1 auto res= std::chrono::duration (diff).count(); 2 return res; 3 } 4 5 int producer(std::promise&& prom){ 6 std::cout << "PRODUCING THE VALUE 2011\n\n"; 7 std::this_thread::sleep_for(std::chrono::seconds(5)); 8 prom.set_value(2011); 9 } 0 1 void consumer(std::shared_future fut,std::chrono::steady_clock::duration dur){ 2 auto start = std::chrono::steady_clock::now(); 3 std::future_status status= fut.wait_until(std::chrono::steady_clock::now() + dur); 4 if ( status == std::future_status::ready ){ 5 std::lock_guard lockCout(coutMutex); 6 std::cout << std::this_thread::get_id() << " ready => Result: " << fut.get() << std::endl; 7 } 8 else{ 9 std::lock_guard lockCout(coutMutex); 0 std::cout << std::this_thread::get_id() << " stopped waiting." << std::endl; 1 } 2 auto end= std::chrono::steady_clock::now(); 3 std::lock_guard lockCout(coutMutex); 4 std::cout << std::this_thread::get_id() << " waiting time: " << getDifference(start,end) << " ms" << std::endl; 5 } 6 7 void consumePeriodically(std::shared_future fut){ 8 auto start = std::chrono::steady_clock::now(); 9 std::future_status status; 0 do { 1 std::this_thread::sleep_for(std::chrono::milliseconds(700)); 2 status = fut.wait_for(std::chrono::seconds(0)); 3 if (status == std::future_status::timeout) { 4 std::lock_guard lockCout(coutMutex); 5 std::cout << " " << std::this_thread::get_id() << " still waiting." << std::endl; 6 } 7 if (status == std::future_status::ready) { 8 std::lock_guard lockCout(coutMutex); 9 std::cout << " " << std::this_thread::get_id() << " waiting done => Result: " << fut.get() << std::endl; 0 } 1 } while (status != std::future_status::ready); 2 auto end= std::chrono::steady_clock::now(); 3 std::lock_guard lockCout(coutMutex); 4 std::cout << " " << std::this_thread::get_id() << " waiting time: " << getDifference(start,end) << " ms" << std::endl; 5 } 6 7 void consumeWithBackoff(std::shared_future fut){ 8 auto start = std::chrono::steady_clock::now(); 9 std::future_status status; 0 auto dur= std::chrono::milliseconds(1); 1 do { 2 std::this_thread::sleep_for(dur); 3 status = fut.wait_for(std::chrono::seconds(0)); 4 dur *= 2; 5 if (status == std::future_status::timeout) { 6 std::lock_guard lockCout(coutMutex); 7 std::cout << " " << std::this_thread::get_id() << " still waiting." << std::endl; 8 } 9 if (status == std::future_status::ready) { 0 std::lock_guard lockCout(coutMutex); 1 std::cout << " " << std::this_thread::get_id() << " waiting done => Result: " << fut.get() << std::endl; 2 } 3 } while (status != std::future_status::ready); 4 auto end= std::chrono::steady_clock::now(); 5 std::lock_guard lockCout(coutMutex); 6 std::cout << " " << std::this_thread::get_id() << " waiting time: " << getDifference(start,end) << " ms" << std::endl; 7 } 8 9 int main(){ 0 1 std::cout << std::endl; 2 3 std::promise prom; 4 std::shared_future future= prom.get_future(); 5 std::thread producerThread(producer,std::move(prom)); 6 7 std::thread consumerThread1(consumer,future,std::chrono::seconds(4)); 8 std::thread consumerThread2(consumer,future,std::chrono::seconds(20)); 9 std::thread consumerThread3(consumePeriodically,future); 0 std::thread consumerThread4(consumeWithBackoff,future); 1 2 consumerThread1.join(); 3 consumerThread2.join(); 4 consumerThread3.join(); 5 consumerThread4.join(); 6 producerThread.join(); 7 8 std::cout << std::endl; 9 0 }