{"id":213,"date":"2014-11-12T07:35:00","date_gmt":"2014-11-12T07:35:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2014\/11\/12\/resumable-functions-in-c\/"},"modified":"2019-02-18T18:05:11","modified_gmt":"2019-02-18T18:05:11","slug":"resumable-functions-in-c","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/resumable-functions-in-c\/","title":{"rendered":"Resumable functions in C++"},"content":{"rendered":"<p>Last year, in a CTP release, we had provided <a href=\"http:\/\/blogs.msdn.com\/b\/vcblog\/archive\/2013\/12\/20\/asynchronous-programming-in-c-using-resumable-functions-and-await.aspx\">a glimpse<\/a> into resumable functions and await support in the Visual C++ compiler. In Visual Studio 2015 Preview we have gotten further along that journey and provided a more general purpose solution. This Preview release provides experimental implementation for a proposal called &#8220;<a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2014\/n4134.pdf\">Resumable functions<\/a>&#8221; for the ISO C++ Standard. This is still work in progress but we believe this is the right time to open up the discussion and seek design feedback. An excellent overview of the topic is already available through <a href=\"https:\/\/www.youtube.com\/watch?v=KUhSjfSbINE\">this CppCon video<\/a>. The slides from that presentation are also available <a href=\"https:\/\/github.com\/CppCon\/CppCon2014\/tree\/master\/Presentations\/await%202.0%20-%20Stackless%20Resumable%20Functions\">here<\/a>.<\/p>\n<p>As of this preview, this feature only works for x64 targets. In order to use this experimental feature you will need to include some new headers (e.g. &#8220;<span style=\"color: #a31515;font-family: Consolas;font-size: 9pt;background-color: white\">&lt;experimental\/resumable&gt;<\/span>&#8220;) in your source files as well as specify the switch &#8220;\/await&#8221; on the compiler command-line.<\/p>\n<p>This feature is built upon the concept of a coroutine which you might have encountered in other languages such as Python, Ruby etc. It is a generalized routine entity which supports operations like suspend and resume in addition to the traditional invoke and return operations. Very simply, it can be thought of as a method which, instead of returning to the caller, stops dead in the middle of processing and yields a value to the caller. The next time the coroutine is called, it resumes where it left off until it yields another value.<\/p>\n<p>Here are a few code examples to get you started with the key aspects of this feature:<\/p>\n<p><span style=\"text-decoration: underline\"><strong>Asynchronous operations <\/strong><\/span><\/p>\n<p>The below code snippet shows how the code would look like for a function that waits for a long running operation like a computation or I\/O. Note the usage of the proposed &#8216;__await&#8217; keyword meant to signify waiting for the result of an asynchronous operation.<\/p>\n<p><span style=\"color: blue;font-family: Consolas;font-size: 9pt;background-color: white\">#include<span style=\"color: black\"> <span style=\"color: #a31515\">&lt;future&gt;<\/span><\/span><\/span><\/p>\n<p><span style=\"color: blue;font-family: Consolas;font-size: 9pt;background-color: white\">using<span style=\"color: black\"> <span style=\"color: blue\">namespace<span style=\"color: black\"> std; <\/span><\/span><\/span><\/span><br \/> <span style=\"color: blue;font-family: Consolas;font-size: 9pt;background-color: white\">using<span style=\"color: black\"> <span style=\"color: blue\">namespace<span style=\"color: black\"> std::chrono; <\/span><\/span><\/span><\/span><br \/> &nbsp;<br \/> <span style=\"color: green;font-family: Consolas;font-size: 9pt;background-color: white\">\/\/ this could be some long running computation or I\/O<\/span><br \/> <span style=\"color: #2b91af;font-family: Consolas;font-size: 9pt;background-color: white\">future<span style=\"color: black\">&lt;<span style=\"color: blue\">int<span style=\"color: black\">&gt; calculate_the_answer() <\/span><\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">{ <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">return<span style=\"color: black\"> async([] { <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this_thread::sleep_for(1s); <span style=\"color: blue\">return<span style=\"color: black\"> 42; <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;}); <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">} <\/span><br \/> &nbsp;<br \/> <span style=\"color: green;font-family: Consolas;font-size: 9pt;background-color: white\">\/\/ Here is a resumable function<\/span><br \/> <span style=\"color: #2b91af;font-family: Consolas;font-size: 9pt;background-color: white\">future<span style=\"color: black\">&lt;<span style=\"color: blue\">void<span style=\"color: black\">&gt; coro() { <\/span><\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;printf(<span style=\"color: #a31515\">&#8220;Started waiting&#8230; n&#8221;<span style=\"color: black\">); <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">auto<span style=\"color: black\"> result = <span style=\"color: blue\">__await<span style=\"color: black\"> calculate_the_answer(); <\/span><\/span><\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;printf(<span style=\"color: #a31515\">&#8220;got %d. n&#8221;<span style=\"color: black\">, result); <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">} <\/span><br \/> &nbsp;<br \/> <span style=\"color: blue;font-family: Consolas;font-size: 9pt;background-color: white\">int<span style=\"color: black\"> <span style=\"color: #6f008a\">_tmain<span style=\"color: black\">(<span style=\"color: blue\">int<span style=\"color: black\"> <span style=\"color: gray\">argc<span style=\"color: black\">, <span style=\"color: #2b91af\">_TCHAR<span style=\"color: black\">* <span style=\"color: gray\">argv<span style=\"color: black\">[]) <\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">{ <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;coro().get(); <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">}<\/span><\/p>\n<p><span style=\"text-decoration: underline\"><strong>Generator pattern <\/strong><\/span><\/p>\n<p>The below code snippet demonstrates the usage of the proposed &#8216;__yield_value&#8217; keyword in the generator pattern where the generator coroutine is able to &#8220;yield&#8221; the values back to the calling function and can also be cancelled on demand.<\/p>\n<p><span style=\"color: blue;font-family: Consolas;font-size: 9pt;background-color: white\">#include<span style=\"color: black\"> <span style=\"color: #a31515\">&lt;iostream&gt;<\/span><\/span><\/span><br \/> <span style=\"color: blue;font-family: Consolas;font-size: 9pt;background-color: white\">#include<span style=\"color: black\"> <span style=\"color: #a31515\">&lt;experimental\/generator&gt;<\/span><\/span><\/span><br \/> &nbsp;<br \/> <span style=\"color: blue;font-family: Consolas;font-size: 9pt;background-color: white\">using<span style=\"color: black\"> <span style=\"color: blue\">namespace<span style=\"color: black\"> std::experimental; <\/span><\/span><\/span><\/span><br \/> <span style=\"color: blue;font-family: Consolas;font-size: 9pt;background-color: white\">using<span style=\"color: black\"> <span style=\"color: blue\">namespace<span style=\"color: black\"> std; <\/span><\/span><\/span><\/span><br \/> &nbsp;<br \/> <span style=\"color: #2b91af;font-family: Consolas;font-size: 9pt;background-color: white\">generator<span style=\"color: black\">&lt;<span style=\"color: blue\">int<span style=\"color: black\">&gt; fib() <\/span><\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">{ <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&amp;n\nbsp;&nbsp;&nbsp;<span style=\"color: blue\">int<span style=\"color: black\"> a = 0; <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">int<span style=\"color: black\"> b = 1; <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">for<span style=\"color: black\"> (;;) { <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">__yield_value<span style=\"color: black\"> a; <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">auto<span style=\"color: black\"> next = a + b; <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a = b; <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b = next; <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;} <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">} <\/span><br \/> &nbsp;<br \/> <span style=\"color: blue;font-family: Consolas;font-size: 9pt;background-color: white\">int<span style=\"color: black\"> <span style=\"color: #6f008a\">_tmain<span style=\"color: black\">(<span style=\"color: blue\">int<span style=\"color: black\"> <span style=\"color: gray\">argc<span style=\"color: black\">, <span style=\"color: #2b91af\">_TCHAR<span style=\"color: black\">* <span style=\"color: gray\">argv<span style=\"color: black\">[]) <\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">{ <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">for<span style=\"color: black\"> (v : fib()) { <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">if<span style=\"color: black\"> (v &gt; 50) <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">break<span style=\"color: black\">; <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout &lt;&lt; v &lt;&lt; endl; <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;} <\/span><br \/> <span style=\"font-size: 9pt\"><span style=\"color: black;font-family: Consolas;background-color: white\">}<\/span> <\/span><\/p>\n<p><span style=\"text-decoration: underline\"><strong>Reactive Streams <\/strong><\/span><\/p>\n<p>The below code pattern demonstrates the usage of the proposed &#8216;for __await&#8217; keyword in a scenario where a coroutine (Ticks) produces an asynchronous stream of values and a function (Sum) consumes those values. The coroutine TimeStamp demonstrates the scenario where a coroutine consumes an incoming stream, process it and outputs it to whoever is waiting for it.<\/p>\n<p><span style=\"color: green;font-family: Consolas;font-size: 9pt;background-color: white\">\/\/As a consumer<\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">future&lt;<span style=\"color: blue\">int<span style=\"color: black\">&gt; Sum(async_read_stream&lt;<span style=\"color: blue\">int<span style=\"color: black\">&gt; &amp; input) <\/span><\/span><\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">{ <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">int<span style=\"color: black\"> result = 0; <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\"><strong>for<span style=\"color: black\"> __await<\/span><\/strong>(v : input)<\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;{ <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result += v; <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;} <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">return<span style=\"color: black\"> result; <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">} <\/span><br \/> &nbsp;<br \/> <span style=\"color: green;font-family: Consolas;font-size: 9pt;background-color: white\">\/\/As a producer :<\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">async_generator&lt;<span style=\"color: blue\">int<span style=\"color: black\">&gt; Ticks() <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">{ <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">for<span style=\"color: black\"> (<span style=\"color: blue\">int<span style=\"color: black\"> tick = 0;; ++tick) <\/span><\/span><\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;{ <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">__yield_value<span style=\"color: black\"> tick; <\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__await sleep_for(1ms); <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;} <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">} <\/span><br \/> &nbsp;<br \/> <span style=\"color: green;font-family: Consolas;font-size: 9pt;background-color: white\">\/\/As a transformer : (adds a timestamp to every observed value)<\/span><br \/> <span style=\"color: blue;font-family: Consolas;font-size: 9pt;background-color: white\">template<span style=\"color: black\">&lt;<span style=\"color: blue\">class<span style=\"color: black\"> T&gt; <\/span><\/span><\/span><\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">async_generator&lt;pair&lt;T, system_clock::time_point&gt;&gt; <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">Timestamp(async_read_stream&lt;T&gt; S) <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">{ <\/span><br \/> <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: blue\">for<span style=\"color: black\"> __await(v: S) <\/span><\/span><\/span><\/p>\n<p style=\"margin-left: 36pt\"><span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">__yield_value { v, system_clock::now() }; <\/span><\/p>\n<p><span style=\"font-size: 9pt\"><span style=\"color: black;font-family: Consolas;background-color: white\">}<\/span> <\/span><\/p>\n<p>These are just some of the examples of this feature. We will continue our work in this area beyond this Preview release and hope to add more coverage, better user experience and in-built support for more high-level scenarios in upcoming releases. However, we hope you will like what you have seen so far, play with this feature, find novel uses for the base concepts and functionality. We look forward to hearing all your feedback.<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last year, in a CTP release, we had provided a glimpse into resumable functions and await support in the Visual C++ compiler. In Visual Studio 2015 Preview we have gotten further along that journey and provided a more general purpose solution. This Preview release provides experimental implementation for a proposal called &#8220;Resumable functions&#8221; for the [&hellip;]<\/p>\n","protected":false},"author":263,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[8],"class_list":["post-213","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-announcement"],"acf":[],"blog_post_summary":"<p>Last year, in a CTP release, we had provided a glimpse into resumable functions and await support in the Visual C++ compiler. In Visual Studio 2015 Preview we have gotten further along that journey and provided a more general purpose solution. This Preview release provides experimental implementation for a proposal called &#8220;Resumable functions&#8221; for the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/263"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=213"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/213\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=213"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}