{"id":4961,"date":"2016-09-26T07:19:01","date_gmt":"2016-09-26T07:19:01","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/sleep-and-wait\/"},"modified":"2023-06-26T12:41:22","modified_gmt":"2023-06-26T12:41:22","slug":"sleep-and-wait","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/sleep-and-wait\/","title":{"rendered":"Sleep and Wait"},"content":{"rendered":"<p>The new time library is an important component of the threading interface. As well, as threads, locks, and condition variables understanding time. All four have in common that they can sleep, wait or block until a time point or for a duration.<\/p>\n<p><!--more--><\/p>\n<h2>Convention<\/h2>\n<p>The methods for handling time in multithreading programs follow a simple convention. Methods ending with <span style=\"font-family: courier new,courier;\">_for<\/span> having to be parametrized by a time duration; member functions ending with <span style=\"font-family: courier new,courier;\">_until<\/span> by a time point. I presented the <a href=\"https:\/\/www.modernescpp.com\/index.php\/time-duration\">time duration <\/a>and <a href=\"https:\/\/www.modernescpp.com\/index.php\/time-point\">time point <\/a>in separate posts. Here is a concise overview of sleeping, blocking, and waiting methods.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4959\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/untilAndForEng.png\" alt=\"untilAndForEng\" width=\"700\" height=\"161\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/untilAndForEng.png 1130w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/untilAndForEng-300x69.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/untilAndForEng-1024x236.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/untilAndForEng-768x177.png 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<p><span style=\"font-family: courier new,courier;\">in2min<\/span> stand for a time 2 minutes in the future.<span style=\"font-family: courier new,courier;\"> 2s<\/span> is a time duration of 2 seconds. Although I use <span style=\"font-family: courier new,courier;\">auto<\/span> it&#8217;s very verbose to define the time point <span style=\"font-family: courier new,courier;\">in2min:<\/span> <span style=\"font-family: courier new,courier;\">auto in2min= std::chrono::steady_clock::now() + std::chrono::minutes(2). <\/span>To the rescue, we have time literals in C++14, like<span style=\"font-family: courier new,courier;\"> <span style=\"font-family: courier new,courier;\">2s. <\/span><\/span><span style=\"font-family: courier new,courier;\"><\/span> C++14 has more literal for <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/chrono\/duration\">typical time durations. <\/a><\/p>\n<p>Now the practice.<\/p>\n<\/p>\n<h2>Various waiting strategies<\/h2>\n<p>First, I want to describe the various waiting strategies.<\/p>\n<p>The key idea of the program is that the promise provides its result for four shared futures. That&#8217;s possible because I used<span style=\"font-family: courier new, courier;\"> std::shared_future<\/span>. Each future has a different waiting strategy. All promises and futures will be executed in different threads. For the sake of simplicity, I will, in the rest of the posts, only speak about a waiting thread, although the future is indeed waiting. You can read the details about the promise and the future <a href=\"https:\/\/www.modernescpp.com\/index.php\/promise-and-future\">here.<\/a><\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li><strong><span style=\"font-family: courier new,courier;\">consumeThread1:<\/span><\/strong> Waits up to 4 seconds for the result of the promise.<\/li>\n<li><strong><span style=\"font-family: courier new,courier;\">consumeThread2:<\/span><\/strong> Waits up to 20 seconds for the result of the promise.<\/li>\n<li><strong><span style=\"font-family: courier new,courier;\">consumeThread3:<\/span><\/strong> Asks the promise for the result and goes back to sleep for 700 milliseconds.<\/li>\n<li><strong><span style=\"font-family: comic sans ms,sans-serif;\"><span style=\"font-family: courier new,courier;\">consumeThread4:<\/span><\/span><\/strong> Asks the promise for the result and goes back to sleep. Its sleep duration starts with one millisecond and doubles each time.<\/li>\n<\/ul>\n<p>Here is the program.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\">  1\r\n  2\r\n  3\r\n  4\r\n  5\r\n  6\r\n  7\r\n  8\r\n  9\r\n 10\r\n 11\r\n 12\r\n 13\r\n 14\r\n 15\r\n 16\r\n 17\r\n 18\r\n 19\r\n 20\r\n 21\r\n 22\r\n 23\r\n 24\r\n 25\r\n 26\r\n 27\r\n 28\r\n 29\r\n 30\r\n 31\r\n 32\r\n 33\r\n 34\r\n 35\r\n 36\r\n 37\r\n 38\r\n 39\r\n 40\r\n 41\r\n 42\r\n 43\r\n 44\r\n 45\r\n 46\r\n 47\r\n 48\r\n 49\r\n 50\r\n 51\r\n 52\r\n 53\r\n 54\r\n 55\r\n 56\r\n 57\r\n 58\r\n 59\r\n 60\r\n 61\r\n 62\r\n 63\r\n 64\r\n 65\r\n 66\r\n 67\r\n 68\r\n 69\r\n 70\r\n 71\r\n 72\r\n 73\r\n 74\r\n 75\r\n 76\r\n 77\r\n 78\r\n 79\r\n 80\r\n 81\r\n 82\r\n 83\r\n 84\r\n 85\r\n 86\r\n 87\r\n 88\r\n 89\r\n 90\r\n 91\r\n 92\r\n 93\r\n 94\r\n 95\r\n 96\r\n 97\r\n 98\r\n 99\r\n100\r\n101\r\n102<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ sleepAndWait.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;utility&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;future&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;thread&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;utility&gt;<\/span>\r\n\r\nstd::mutex coutMutex;\r\n\r\n<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> getDifference(<span style=\"color: #0000ff;\">const<\/span> std::chrono::steady_clock::time_point&amp; tp1,<span style=\"color: #0000ff;\">const<\/span> std::chrono::steady_clock::time_point&amp; tp2){\r\n    <span style=\"color: #0000ff;\">auto<\/span> diff= tp2- tp1;\r\n    <span style=\"color: #0000ff;\">auto<\/span> res= std::chrono::duration &lt;<span style=\"color: #2b91af;\">double<\/span>, std::milli&gt; (diff).count();\r\n    <span style=\"color: #0000ff;\">return<\/span> res;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span>producer(std::promise&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;&amp;&amp; prom){\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"PRODUCING THE VALUE 2011\\n\\n\"<\/span>; \r\n    std::this_thread::sleep_for(std::chrono::seconds(5));\r\n    prom.set_value(2011);\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> consumer(std::shared_future&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; fut,std::chrono::steady_clock::duration dur){\r\n    <span style=\"color: #0000ff;\">auto<\/span> start = std::chrono::steady_clock::now();\r\n    std::future_status status= fut.wait_until(std::chrono::steady_clock::now() + dur);\r\n    <span style=\"color: #0000ff;\">if<\/span> ( status == std::future_status::ready ){\r\n        std::lock_guard&lt;std::mutex&gt; lockCout(coutMutex);\r\n        std::cout &lt;&lt; std::this_thread::get_id() &lt;&lt; <span style=\"color: #a31515;\">\" ready =&gt; Result: \"<\/span> &lt;&lt; fut.get() &lt;&lt; std::endl;\r\n    }\r\n    <span style=\"color: #0000ff;\">else<\/span>{\r\n        std::lock_guard&lt;std::mutex&gt; lockCout(coutMutex);\r\n        std::cout &lt;&lt; std::this_thread::get_id() &lt;&lt; <span style=\"color: #a31515;\">\" stopped waiting.\"<\/span> &lt;&lt; std::endl;\r\n    }\r\n    <span style=\"color: #0000ff;\">auto<\/span> end= std::chrono::steady_clock::now();\r\n    std::lock_guard&lt;std::mutex&gt; lockCout(coutMutex);\r\n    std::cout &lt;&lt; std::this_thread::get_id() &lt;&lt; <span style=\"color: #a31515;\">\" waiting time: \"<\/span> &lt;&lt; getDifference(start,end) &lt;&lt; <span style=\"color: #a31515;\">\" ms\"<\/span> &lt;&lt; std::endl;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> consumePeriodically(std::shared_future&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; fut){\r\n    <span style=\"color: #0000ff;\">auto<\/span> start = std::chrono::steady_clock::now();\r\n    std::future_status status;\r\n    <span style=\"color: #0000ff;\">do<\/span> {\r\n        std::this_thread::sleep_for(std::chrono::milliseconds(700));\r\n        status = fut.wait_for(std::chrono::seconds(0));\r\n        <span style=\"color: #0000ff;\">if<\/span> (status == std::future_status::timeout) {\r\n            std::lock_guard&lt;std::mutex&gt; lockCout(coutMutex);\r\n            std::cout &lt;&lt; <span style=\"color: #a31515;\">\"     \"<\/span> &lt;&lt; std::this_thread::get_id() &lt;&lt; <span style=\"color: #a31515;\">\" still waiting.\"<\/span> &lt;&lt; std::endl;\r\n        }\r\n        <span style=\"color: #0000ff;\">else<\/span> <span style=\"color: #0000ff;\">if<\/span> (status == std::future_status::ready) {\r\n            std::lock_guard&lt;std::mutex&gt; lockCout(coutMutex);\r\n            std::cout &lt;&lt; <span style=\"color: #a31515;\">\"     \"<\/span> &lt;&lt; std::this_thread::get_id() &lt;&lt; <span style=\"color: #a31515;\">\" waiting done =&gt; Result: \"<\/span> &lt;&lt; fut.get() &lt;&lt; std::endl;\r\n        }\r\n    } <span style=\"color: #0000ff;\">while<\/span> (status != std::future_status::ready); \r\n    <span style=\"color: #0000ff;\">auto<\/span> end= std::chrono::steady_clock::now();\r\n    std::lock_guard&lt;std::mutex&gt; lockCout(coutMutex);\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"     \"<\/span> &lt;&lt; std::this_thread::get_id() &lt;&lt; <span style=\"color: #a31515;\">\" waiting time: \"<\/span> &lt;&lt; getDifference(start,end) &lt;&lt; <span style=\"color: #a31515;\">\" ms\"<\/span> &lt;&lt; std::endl;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> consumeWithBackoff(std::shared_future&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; fut){\r\n    <span style=\"color: #0000ff;\">auto<\/span> start = std::chrono::steady_clock::now();\r\n    std::future_status status;\r\n    <span style=\"color: #0000ff;\">auto<\/span> dur= std::chrono::milliseconds(1);\r\n    <span style=\"color: #0000ff;\">do<\/span> {\r\n        std::this_thread::sleep_for(dur);\r\n        status = fut.wait_for(std::chrono::seconds(0));\r\n        dur *= 2;\r\n        <span style=\"color: #0000ff;\">if<\/span> (status == std::future_status::timeout) {\r\n            std::lock_guard&lt;std::mutex&gt; lockCout(coutMutex);\r\n            std::cout &lt;&lt; <span style=\"color: #a31515;\">\"         \"<\/span> &lt;&lt; std::this_thread::get_id() &lt;&lt; <span style=\"color: #a31515;\">\" still waiting.\"<\/span> &lt;&lt; std::endl;\r\n        }\r\n        <span style=\"color: #0000ff;\">else<\/span> <span style=\"color: #0000ff;\">if<\/span> (status == std::future_status::ready) {\r\n            std::lock_guard&lt;std::mutex&gt; lockCout(coutMutex);\r\n            std::cout &lt;&lt; <span style=\"color: #a31515;\">\"         \"<\/span> &lt;&lt; std::this_thread::get_id() &lt;&lt; <span style=\"color: #a31515;\">\" waiting done =&gt; Result: \"<\/span> &lt;&lt; fut.get() &lt;&lt; std::endl;\r\n        }\r\n    } <span style=\"color: #0000ff;\">while<\/span> (status != std::future_status::ready);\r\n    <span style=\"color: #0000ff;\">auto<\/span> end= std::chrono::steady_clock::now();\r\n    std::lock_guard&lt;std::mutex&gt; lockCout(coutMutex);\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"         \"<\/span> &lt;&lt; std::this_thread::get_id() &lt;&lt; <span style=\"color: #a31515;\">\" waiting time: \"<\/span> &lt;&lt; getDifference(start,end) &lt;&lt; <span style=\"color: #a31515;\">\" ms\"<\/span> &lt;&lt; std::endl;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n    \r\n    std::cout &lt;&lt; std::endl;\r\n\r\n    std::promise&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; prom;\r\n    std::shared_future&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; future= prom.get_future();\r\n    std::<span style=\"color: #0000ff;\">thread<\/span> producerThread(producer,std::move(prom));\r\n    \r\n    std::<span style=\"color: #0000ff;\">thread<\/span> consumerThread1(consumer,future,std::chrono::seconds(4));\r\n    std::<span style=\"color: #0000ff;\">thread<\/span> consumerThread2(consumer,future,std::chrono::seconds(20));\r\n    std::<span style=\"color: #0000ff;\">thread<\/span> consumerThread3(consumePeriodically,future);\r\n    std::<span style=\"color: #0000ff;\">thread<\/span> consumerThread4(consumeWithBackoff,future);\r\n    \r\n    consumerThread1.join();\r\n    consumerThread2.join();\r\n    consumerThread3.join();\r\n    consumerThread4.join();\r\n    producerThread.join();\r\n    \r\n    std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I create in the main function (line 85) the promise, use the promise to create the associated future (line 86), and move the promise to a separate thread (line 87). I have to move the promise in the thread&nbsp;because it doesn&#8217;t support copy semantic. That will not hold for the shared futures (lines 89 &#8211; 92). They support copy semantics and can therefore be copied.<\/p>\n<p>Before I talk about the work package of the thread, let me say a few words about the auxiliary function <span style=\"font-family: courier new,courier;\">getDifference<\/span> (lines 11 &#8211; 15). The function takes two-time points and returns the time duration in milliseconds. I will use the function a few times.&nbsp;<\/p>\n<p>What about the threads?<\/p>\n<ul>\n<li><span style=\"font-family: courier new,courier;\"><strong>producerThread<\/strong>: <\/span>Executes the function<span style=\"font-family: courier new,courier;\"> producer <\/span>(lines 17 &#8211; 21) and publishes its result 2011 after 5 seconds of sleep. This is the result the futures are waiting for.<\/li>\n<li><span style=\"font-family: courier new,courier;\"><strong>consumerThread1:<\/strong><\/span> Executes the function <span style=\"font-family: courier new,courier;\">consumer<\/span> (lines 23 &#8211; 37). The thread is waiting for at most 4 seconds (line 25) before continuing its work. This waiting period is not long enough to get the result of the promise.<\/li>\n<li><span style=\"font-family: courier new,courier;\"><strong>consumerThread2:<\/strong><\/span> Executes the function <span style=\"font-family: courier new,courier;\">consumer<\/span> (lines 23 &#8211; 37). The thread is waiting at most 20 seconds before continuing its work.<\/li>\n<li><span style=\"font-family: courier new,courier;\"><strong>consumerThread3:<\/strong><\/span>Executes the function <span style=\"font-family: courier new,courier;\">consumePeriodically<\/span> (lines 39 &#8211; 57). It sleeps for 700 milliseconds (line 43) and asks for the result of the promise (line 44). Because of the 0 seconds in line 44 (<span style=\"font-family: courier new,courier;\">std::chrono::seconds(0)<\/span>) there is&nbsp;no waiting. If the calculation result is available, it will be displayed on line 73.<\/li>\n<li><span style=\"font-family: courier new,courier;\"><strong>consumerThread4:<\/strong><\/span>Executes the function <span style=\"font-family: courier new,courier;\">consumeWithBackoff<\/span> (lines 59 &#8211; 79). It sleeps in the first iteration 1 second and doubles by each further iteration its sleeping period. Otherwise, its strategy is similar to&nbsp;<span style=\"font-family: courier new,courier;\">consumerThread3.<\/span> <span style=\"font-family: courier new,courier;\"><\/span><\/li>\n<\/ul>\n<p>Now to the synchronization of the program. The clock for determining the current time as <span style=\"font-family: courier new,courier;\">std::cout<\/span> are shared variables. But I need no synchronization. First, the method <span style=\"font-family: courier new,courier;\">std::chrono::steady_clock::now()<\/span> is thread-safe (for example, in lines 24 and 34); second, the C++ runtime guarantees that the characters will be written thread-safe to <span style=\"font-family: courier new,courier;\">std::cout<\/span>. For visual reasons, I used a <span style=\"font-family: courier new,courier;\">std::lock_guard<\/span> to wrap <span style=\"font-family: courier new,courier;\">std::cout<\/span> (for example, in lines 27, 31, and 35).<\/p>\n<p>Although the threads write one after the other to <span style=\"font-family: courier new,courier;\">std::cout<\/span> the output is not easy to understand.<\/p>\n<p><span style=\"font-family: courier new,courier;\"><\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4960\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/sleepAndWait.png\" alt=\"sleepAndWait\" style=\"margin: 15px;\" width=\"522\" height=\"616\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/sleepAndWait.png 522w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/sleepAndWait-254x300.png 254w\" sizes=\"auto, (max-width: 522px) 100vw, 522px\" \/><\/p>\n<p>The first output is from the promise. The remaining outputs from the futures. At first, <span style=\"font-family: courier new,courier;\">consumerThread4 <\/span>asks for the result. The output is indented by 8 characters. <span style=\"font-family: courier new, courier;\">consumerThread<\/span>4 also displays its ID. consumerThread3 is immediately following. Its output is indented by 4 characters. <span style=\"font-family: courier new,courier;\"><\/span>The output of <span style=\"font-family: courier new,courier;\">consumerThread1<\/span> and <span style=\"font-family: courier new,courier;\">consumerThread2<\/span> is not indented.<\/p>\n<ul>\n<li><span style=\"font-family: courier new,courier;\"><strong>consumeThread1:<\/strong> <\/span>Waits unsuccessfully 4000.18 ms seconds without getting the result.<\/li>\n<li><span style=\"font-family: courier new,courier;\"><strong>consumeThread2:<\/strong> <\/span>Gets the result after 5000.3 ms, although its waiting duration is up to 20 seconds.<\/li>\n<li><span style=\"font-family: courier new,courier;\"><strong>consumeThread3:<\/strong> <\/span>Gets the result after 5601.76 ms. That&#8217;s about 5600 milliseconds= 8*7000 milliseconds.<\/li>\n<li><span style=\"font-family: courier new,courier;\"><strong>consumeThread4: <\/strong><\/span>Gets the result after 8193.81 ms. To say it differently. It waits 3 seconds too long.&nbsp;<span style=\"font-family: courier new,courier;\"> <\/span><\/li>\n<\/ul>\n<h2>What&#8217;s next?<\/h2>\n<p>This post finishes my miniseries about the time library. I will write about embedded programming with modern C++ in the next post. Here is the overview of <a href=\"https:\/\/www.modernescpp.com\/index.php\/der-einstieg-in-modernes-c\">my plan.<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The new time library is an important component of the threading interface. As well, as threads, locks, and condition variables understanding time. All four have in common that they can sleep, wait or block until a time point or for a duration.<\/p>\n","protected":false},"author":21,"featured_media":4959,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[369],"tags":[453],"class_list":["post-4961","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-multithreading-application","tag-time"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4961","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=4961"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4961\/revisions"}],"predecessor-version":[{"id":6943,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4961\/revisions\/6943"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/4959"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=4961"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=4961"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=4961"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}