{"id":4772,"date":"2016-06-05T10:03:00","date_gmt":"2016-06-05T10:03:00","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/promise-and-future\/"},"modified":"2023-06-26T12:55:23","modified_gmt":"2023-06-26T12:55:23","slug":"promise-and-future","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/promise-and-future\/","title":{"rendered":"Promise and Future"},"content":{"rendered":"<p>With<span style=\"font-family: courier new,courier;\"> std::promise<\/span> and<span style=\"font-family: courier new,courier;\"> std::future, <\/span>you have full control over the task.<\/p>\n<p><!--more--><\/p>\n<h2>Full control over the task<\/h2>\n<p>A <span style=\"font-family: courier new,courier;\">std::promise<\/span> permits<\/p>\n<ul>\n<li>to set a value, a notification, or an exception. That result can, in addition, be delayed provided by the promise.<\/li>\n<\/ul>\n<p><span style=\"font-family: courier new,courier;\"><span style=\"font-family: arial,helvetica,sans-serif;\">A<\/span> std::future<\/span> permits to<\/p>\n<ul>\n<li>pick up of the value from the promise.<\/li>\n<li>asks the promise if the value is available.<\/li>\n<li>wait for the notification of the promise. That waiting can be done with a relative time duration or an absolute time point. =&gt; Replacement for <a href=\"https:\/\/www.modernescpp.com\/index.php\/condition-variables\">condition variables. <\/a><\/li>\n<li>create a shared future (<span style=\"font-family: courier new,courier;\">std::shared_future<\/span>).<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>Both <a href=\"https:\/\/www.modernescpp.com\/index.php\/tasks\">communication endpoints<\/a> promise and the future can be moved in a separate thread. So the communication is taking place between threads.<\/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\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n49\r\n50<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ promiseFuture.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;future&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&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\n<span style=\"color: #2b91af;\">void<\/span> product(std::promise&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;&amp;&amp; intPromise, <span style=\"color: #2b91af;\">int<\/span> a, <span style=\"color: #2b91af;\">int<\/span> b){\r\n  intPromise.set_value(a*b);\r\n}\r\n\r\n<span style=\"color: #0000ff;\">struct<\/span> Div{\r\n\r\n  <span style=\"color: #2b91af;\">void<\/span> <span style=\"color: #0000ff;\">operator<\/span>() (std::promise&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;&amp;&amp; intPromise, <span style=\"color: #2b91af;\">int<\/span> a, <span style=\"color: #2b91af;\">int<\/span> b) <span style=\"color: #0000ff;\">const<\/span> {\r\n    intPromise.set_value(a\/b);\r\n  }\r\n\r\n};\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  <span style=\"color: #2b91af;\">int<\/span> a= 20;\r\n  <span style=\"color: #2b91af;\">int<\/span> b= 10;\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  <span style=\"color: #008000;\">\/\/ define the promises<\/span>\r\n  std::promise&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; prodPromise;\r\n  std::promise&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; divPromise;\r\n\r\n  <span style=\"color: #008000;\">\/\/ get the futures<\/span>\r\n  std::future&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; prodResult= prodPromise.get_future();\r\n  std::future&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; divResult= divPromise.get_future();\r\n\r\n  <span style=\"color: #008000;\">\/\/ calculate the result in a separat thread<\/span>\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> prodThread(product,std::move(prodPromise),a,b);\r\n  Div div;\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> divThread(div,std::move(divPromise),a,b);\r\n\r\n  <span style=\"color: #008000;\">\/\/ get the result<\/span>\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"20*10= \"<\/span> &lt;&lt; prodResult.get() &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"20\/10= \"<\/span> &lt;&lt; divResult.get() &lt;&lt; std::endl;\r\n\r\n  prodThread.join();\r\n  \r\n  divThread.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>The thread <span style=\"font-family: courier new,courier;\">prodThread<\/span> (line 36) uses the function <span style=\"font-family: courier new,courier;\">product<\/span> (line 8 -10), the <span style=\"font-family: courier new,courier;\">prodPromise<\/span> (line 32), and the numbers a and b. To understand the arguments of the thread <span style=\"font-family: courier new,courier;\">prodThread,<\/span> you have to look at the function&#8217;s signature. <span style=\"font-family: courier new,courier;\">prodThread<\/span> needs as the first argument a callable. This is the already mentioned function <span style=\"font-family: courier new,courier;\">product.<\/span> <span style=\"font-family: courier new,courier;\">product<\/span> needs a promise of the kind rvalue reference (<span style=\"font-family: courier new,courier;\">std::promise&lt;int&gt;&amp;&amp; intPromise<\/span>) and two numbers. These are exactly the last three arguments of the thread <span style=\"font-family: courier new,courier;\">prodThread.<\/span>&nbsp;<span style=\"font-family: courier new,courier;\">std::move<\/span>&nbsp;in line 36 creates the rvalue reference. The rest is a piece of cake. The thread <span style=\"font-family: courier new,courier;\">divThread<\/span> (line38) divides the two numbers a and b. For is a job, it uses the instances <span style=\"font-family: courier new,courier;\">div<\/span> of the class <span style=\"font-family: courier new,courier;\">Div<\/span> (line 12 &#8211; 18). <span style=\"font-family: courier new,courier;\">div<\/span> is a function object.<\/p>\n<p>The futures picks up the results by the calls<span style=\"font-family: courier new,courier;\"> prodResult.get()<\/span> and <span style=\"font-family: courier new,courier;\">divResult.get()<\/span>.&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4770\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/06\/promiseFuture.png\" alt=\"promiseFuture\" width=\"579\" height=\"197\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/06\/promiseFuture.png 579w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/06\/promiseFuture-300x102.png 300w\" sizes=\"auto, (max-width: 579px) 100vw, 579px\" \/><\/p>\n<p>Per default, there is a one-to-one relationship between the promise and the future. But <span style=\"font-family: courier new,courier;\">std::shared_future<\/span> supports a one-to-many relation between a promise and many futures.<\/p>\n<\/p>\n<h2>std::shared_future<\/h2>\n<p>A <span style=\"font-family: courier new,courier;\">std::shared_future&nbsp; <br \/><\/span><\/p>\n<ul>\n<li>permits you to ask the promise independent of the other associated futures.<\/li>\n<li>has the same interface as a <span style=\"font-family: courier new,courier;\">std::future<\/span>.<\/li>\n<li>can be created by a <span style=\"font-family: courier new,courier;\">std::future fut <\/span>with the call<span style=\"font-family: courier new,courier;\"> fut.share()<\/span>.<\/li>\n<li>can be created by a&nbsp;<span style=\"font-family: courier new,courier;\">std::promise&nbsp;divPromise <span style=\"font-family: arial,helvetica,sans-serif;\">with the call <\/span>std::shared_future&lt;int&gt; divResult= divPromise.get_future().<\/span><\/li>\n<\/ul>\n<p>The managing of <span style=\"font-family: courier new,courier;\">std::shared_future<\/span> is special.<\/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\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n49\r\n50\r\n51\r\n52\r\n53\r\n54\r\n55\r\n56\r\n57\r\n58\r\n59\r\n60\r\n61\r\n62\r\n63\r\n64\r\n65\r\n66\r\n67\r\n68\r\n69\r\n70\r\n71\r\n72\r\n73\r\n74\r\n75\r\n76\r\n77<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ sharedFuture.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;exception&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;future&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&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: #0000ff;\">struct<\/span> Div{\r\n\r\n  <span style=\"color: #2b91af;\">void<\/span> <span style=\"color: #0000ff;\">operator<\/span>()(std::promise&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;&amp;&amp; intPromise, <span style=\"color: #2b91af;\">int<\/span> a, <span style=\"color: #2b91af;\">int<\/span> b){\r\n    try{\r\n      <span style=\"color: #0000ff;\">if<\/span> ( b==0 ) <span style=\"color: #0000ff;\">throw<\/span> std::runtime_error(<span style=\"color: #a31515;\">\"illegal division by zero\"<\/span>);\r\n      intPromise.set_value(a\/b);\r\n    }\r\n    <span style=\"color: #0000ff;\">catch<\/span> (...){\r\n      intPromise.set_exception(std::current_exception());\r\n    }\r\n  }\r\n\r\n};\r\n\r\n<span style=\"color: #0000ff;\">struct<\/span> Requestor{\r\n\r\n  <span style=\"color: #2b91af;\">void<\/span> <span style=\"color: #0000ff;\">operator<\/span> ()(std::shared_future&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; shaFut){\r\n\r\n    <span style=\"color: #008000;\">\/\/ lock std::cout<\/span>\r\n    std::lock_guard&lt;std::mutex&gt; coutGuard(coutMutex);\r\n\r\n    <span style=\"color: #008000;\">\/\/ get the thread id<\/span>\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"threadId(\"<\/span> &lt;&lt; std::this_thread::get_id() &lt;&lt; <span style=\"color: #a31515;\">\"): \"<\/span> ;\r\n\r\n    <span style=\"color: #008000;\">\/\/ get the result<\/span>\r\n    try{\r\n      std::cout &lt;&lt; <span style=\"color: #a31515;\">\"20\/10= \"<\/span> &lt;&lt; shaFut.get() &lt;&lt; std::endl;\r\n    }\r\n    <span style=\"color: #0000ff;\">catch<\/span> (std::runtime_error&amp; e){\r\n      std::cout &lt;&lt; e.what() &lt;&lt; std::endl;\r\n    }\r\n  }\r\n\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  <span style=\"color: #008000;\">\/\/ define the promises<\/span>\r\n  std::promise&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; divPromise;\r\n\r\n  <span style=\"color: #008000;\">\/\/ get the futures<\/span>\r\n  std::shared_future&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; divResult= divPromise.get_future();\r\n\r\n  <span style=\"color: #008000;\">\/\/ calculate the result in a separat thread<\/span>\r\n  Div div;\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> divThread(div,std::move(divPromise),20,10);\r\n\r\n  Requestor req;\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> sharedThread1(req,divResult);\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> sharedThread2(req,divResult);\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> sharedThread3(req,divResult);\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> sharedThread4(req,divResult);\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> sharedThread5(req,divResult);\r\n\r\n  divThread.join();\r\n\r\n  sharedThread1.join();\r\n  sharedThread2.join();\r\n  sharedThread3.join();\r\n  sharedThread4.join();\r\n  sharedThread5.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>Both work packages of the promise and the future are in this current example function objects. If you divide into numbers, you must take care of the denominator. It must not be 0. If it is 0, you get an exception. The promise deals with this issue by catching the exception (lines 18 &#8211; 20) and rethrowing it to the future. The <span style=\"font-family: courier new,courier;\">std::future<\/span> catches the exception and displays it in line 40. In line 58, <span style=\"font-family: courier new,courier;\">divPromise<\/span> will be moved and executed in <span style=\"font-family: courier new,courier;\">divThread<\/span>. Accordingly, the <span style=\"font-family: courier new,courier;\">std::shared_future&#8217;s<\/span> are <strong>copied<\/strong> in the five threads. I will emphasize this once more. In opposite to a <span style=\"font-family: courier new,courier;\">std::future<\/span> object, which can only be moved, you can copy a <span style=\"font-family: courier new,courier;\">std::shared_future<\/span> object.<\/p>\n<p>The main thread waits In lines 69 to 73 for its children and shows the results.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4771\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/06\/sharedFuture.png\" alt=\"sharedFuture\" width=\"579\" height=\"245\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/06\/sharedFuture.png 579w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/06\/sharedFuture-300x127.png 300w\" sizes=\"auto, (max-width: 579px) 100vw, 579px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>There is one oddity with <span style=\"font-family: courier new,courier;\">std::async<\/span>, which you should know. The by <span style=\"font-family: courier new,courier;\">std::async<\/span> created future blocks in its destructor until the associated promise is done. Curious? Read the <a href=\"https:\/\/www.modernescpp.com\/index.php\/the-special-futures\">next post.<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>With std::promise and std::future, you have full control over the task.<\/p>\n","protected":false},"author":21,"featured_media":4770,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[366],"tags":[446],"class_list":["post-4772","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-multithreading","tag-tasks"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4772","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=4772"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4772\/revisions"}],"predecessor-version":[{"id":6975,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4772\/revisions\/6975"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/4770"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=4772"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=4772"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=4772"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}