{"id":4761,"date":"2016-05-21T10:41:47","date_gmt":"2016-05-21T10:41:47","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/tasks\/"},"modified":"2023-06-26T12:56:36","modified_gmt":"2023-06-26T12:56:36","slug":"tasks","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/tasks\/","title":{"rendered":"Tasks"},"content":{"rendered":"<p>Tasks were one of the latest additions to the C++11 standard. They give you a better abstraction than threads. In the general case, they should be your first choice.&nbsp;<\/p>\n<p><!--more--><\/p>\n<h2><span style=\"font-family: arial,helvetica,sans-serif;\">&nbsp;Tasks as data channels<br \/><\/span><\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4759\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/tasksEng.png\" alt=\"tasksEng\" width=\"600\" height=\"269\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/tasksEng.png 831w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/tasksEng-300x134.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/tasksEng-768x344.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>Tasks behave like data channels. On one side, the sender sets a value. On the other side, the receiver picks up the value. The sender is called <em>promise<\/em>, the receiver &#8211;&nbsp;<em>future<\/em>. Or to say it in different words, the sender promises to provide a value, which the receiver can pick up in the future.<\/p>\n<p>A few more details. The sender can provide the value for more than one future. Besides a value, the sender can also provide a notification or an exception. The <em>get<\/em> call of the future <em>blocks<\/em>. It means, in case the future calls wait, it must <em>wait<\/em> until the promise puts the value into the channel.<\/p>\n<p>Tasks are available in three variations. As asynchronous function call with<span style=\"font-family: courier new,courier;\"> std::async<\/span>, as simple wrapper for a callable with <span style=\"font-family: courier new,courier;\">std::packaged_task<\/span>, and as the explicit pair <span style=\"font-family: courier new,courier;\">std::promise<\/span> and <span style=\"font-family: courier new,courier;\">std::future<\/span>.<\/p>\n<p>The best way to get the differences between threads and tasks is to compare them.<\/p>\n<\/p>\n<h2>Threads versus Tasks<\/h2>\n<p>This small code example illustrates the difference:<\/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<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #2b91af;\">int<\/span> res;\r\nstd::<span style=\"color: #0000ff;\">thread<\/span> t([&amp;]{res= 3+4;});\r\nt.join();\r\nstd::cout &lt;&lt; res &lt;&lt; std:::endl;\r\n\r\n<span style=\"color: #0000ff;\">auto<\/span> fut=std::async([]{<span style=\"color: #0000ff;\">return<\/span> 3+4;});\r\nstd::cout &lt;&lt; fut.get() &lt;&lt; std::endl;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The child thread and the promise calculate the sum of 3+4 and return the result. The <span style=\"font-family: courier new,courier;\">std::async<\/span>&nbsp;call generates a data channel with both endpoints&nbsp;<span style=\"font-family: courier new,courier;\">fut<\/span> and std::<span style=\"font-family: courier new,courier;\">async.<\/span> <span style=\"font-family: courier new,courier;\">fut<\/span> is a future, std::async &nbsp;is a promise. The future gets the value with the call <span style=\"font-family: 'courier new', courier;\">fut.get()<\/span>. The promise provides this value. The future can act at a later point in time.<\/p>\n<p>What are the differences?<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4760\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/TaskThreadCompareEng.png\" alt=\"TaskThreadCompareEng\" width=\"600\" height=\"321\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/TaskThreadCompareEng.png 784w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/TaskThreadCompareEng-300x161.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/TaskThreadCompareEng-768x411.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>The thread needs the <span style=\"font-family: courier new,courier;\">&lt;thread&gt;&nbsp;header<\/span>; the task needs the <span style=\"font-family: courier new,courier;\">&lt;future&gt;<\/span>&nbsp;header. The participants of the threads are the creator thread and the child thread, and the participants of the task are the promise and the future. The shared variable <span style=\"font-family: 'courier new', courier;\">res<\/span> is the child&#8217;s way of transferring the calculation result to the creator. On the contrary, with the promise and future use of a shared data channel, &nbsp;<span style=\"font-family: courier new,courier;\">std::async<\/span> creates the data channel.<span style=\"font-family: courier new,courier;\"><\/span>Using&nbsp;<span style=\"font-family: courier new,courier;\">fut.get<\/span> the future gets the result. Using threads, you have to protect the shared variable with a lock. But there is implicitly no possibility of a <a href=\"https:\/\/www.modernescpp.com\/index.php?option=com_content&amp;view=article&amp;id=157;threads-sharing-\">race condition <\/a>for the promise and the future. The creator of the threads waits with its<span style=\"font-family: courier new,courier;\"> t.join<\/span> call until its child is done. On the other side, the <span style=\"font-family: courier new,courier;\">fut.get<\/span> call blocks. If there is an exception in the child thread, the child and creator threads terminate. So, in the end, the whole program terminates. The promise can deliver an exception to the future. The future has to handle the exception. While the child thread can only provide values for the creator thread, the promise can send values, exceptions, and notifications to the associated future.&nbsp;<\/p>\n<p>The key difference between threads and tasks is the higher abstraction level of tasks. A task will not automatically generate a thread. Specifically, the C++ runtime decides if a thread should be created. Reasons for the decision are: How heavy is the payload? How many cores are available? How high is the system load?<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>So, that was the fundament for the <a href=\"https:\/\/www.modernescpp.com\/index.php\/asynchronous-function-calls\">next posts <\/a>about tasks. The next one is about <span style=\"font-family: courier new,courier;\">std::async.<\/span><a href=\"https:\/\/www.modernescpp.com\/index.php\/blog\/asynchrone-funktionsaufrufe\"><span style=\"font-family: courier new,courier;\"><\/span><\/a>(<strong>Proofreader Alexey Elymanov<\/strong>)<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tasks were one of the latest additions to the C++11 standard. They give you a better abstraction than threads. In the general case, they should be your first choice.&nbsp;<\/p>\n","protected":false},"author":21,"featured_media":4759,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[366],"tags":[446],"class_list":["post-4761","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\/4761","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=4761"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4761\/revisions"}],"predecessor-version":[{"id":6978,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4761\/revisions\/6978"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/4759"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=4761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=4761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=4761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}