{"id":2131,"date":"2024-07-20T20:47:55","date_gmt":"2024-07-20T20:47:55","guid":{"rendered":"https:\/\/www.w3computing.com\/articles\/?p=2131"},"modified":"2024-07-20T20:47:58","modified_gmt":"2024-07-20T20:47:58","slug":"how-to-use-cpp-coroutines-for-asynchronous-tasks","status":"publish","type":"post","link":"https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/","title":{"rendered":"How to Use C++ Coroutines for Asynchronous Tasks"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">C++ Coroutines, introduced in C++20, offer a powerful way to handle asynchronous tasks. This tutorial aims to guide you through the essentials of using C++ Coroutines for asynchronous programming. We will cover the fundamental concepts, the necessary syntax, and practical examples to ensure you understand how to effectively implement coroutines in your projects. The target audience for this tutorial is developers who are familiar with C++ and have some experience with asynchronous programming but are new to C++ Coroutines.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Understanding Coroutines<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A coroutine is a function that can suspend its execution to be resumed later. Unlike regular functions, which run from start to finish, coroutines can pause execution at certain points, returning control to the caller and then resume from where they left off. This makes coroutines particularly suitable for asynchronous programming, where tasks often need to wait for I\/O operations or other asynchronous events.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Key Concepts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before diving into the code, let&#8217;s understand some key concepts related to coroutines:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Coroutine State<\/strong>: Coroutines maintain their state across suspensions, allowing them to resume execution seamlessly.<\/li>\n\n\n\n<li><strong>Suspension Points<\/strong>: Points within a coroutine where execution can be paused and later resumed.<\/li>\n\n\n\n<li><strong>Promises and Futures<\/strong>: Mechanisms to handle values produced by coroutines.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Coroutine Syntax<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In C++, coroutines are declared using the <code>co_await<\/code>, <code>co_yield<\/code>, and <code>co_return<\/code> keywords. Here&#8217;s a brief overview of these keywords:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>co_await<\/code><\/strong>: Suspends the coroutine until the awaited task completes.<\/li>\n\n\n\n<li><strong><code>co_yield<\/code><\/strong>: Produces a value and suspends the coroutine.<\/li>\n\n\n\n<li><strong><code>co_return<\/code><\/strong>: Completes the coroutine and optionally returns a value.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Setting Up Coroutines<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To use coroutines, you need to include the <code>&lt;coroutine&gt;<\/code> header. Let&#8217;s start by writing a simple coroutine.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;coroutine&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;iostream&gt;<\/span><\/span>\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title\">return_object<\/span> {<\/span>\n    <span class=\"hljs-class\"><span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title\">promise_type<\/span> {<\/span>\n        <span class=\"hljs-function\">return_object <span class=\"hljs-title\">get_return_object<\/span><span class=\"hljs-params\">()<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> {}; }\n        <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::suspend_never <span class=\"hljs-title\">initial_suspend<\/span><span class=\"hljs-params\">()<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> {}; }\n        <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::suspend_never <span class=\"hljs-title\">final_suspend<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">noexcept<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> {}; }\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">return_void<\/span><span class=\"hljs-params\">()<\/span> <\/span>{}\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">unhandled_exception<\/span><span class=\"hljs-params\">()<\/span> <\/span>{ <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">terminate<\/span>(); }\n    };\n};\n\n<span class=\"hljs-function\">return_object <span class=\"hljs-title\">simple_coroutine<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Hello from coroutine\"<\/span> &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n    <span class=\"hljs-keyword\">co_return<\/span>;\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    simple_coroutine();\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Coroutine finished\"<\/span> &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">0<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this example, we define a <code>return_object<\/code> struct with a nested <code>promise_type<\/code> struct. The <code>promise_type<\/code> struct defines how the coroutine handles its lifecycle, including suspension and completion. The <code>simple_coroutine<\/code> function demonstrates a basic coroutine that prints a message and then completes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Asynchronous Tasks with Coroutines<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s move on to a more practical example: performing asynchronous tasks. We&#8217;ll create a coroutine that simulates an asynchronous operation using <code>std::future<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Defining the Awaiter<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">First, we need to define an awaiter. An awaiter is a type that knows how to suspend and resume a coroutine.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;future&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;iostream&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;coroutine&gt;<\/span><\/span>\n\n<span class=\"hljs-keyword\">template<\/span> &lt;<span class=\"hljs-keyword\">typename<\/span> T&gt;\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title\">async_task<\/span> {<\/span>\n    <span class=\"hljs-class\"><span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title\">promise_type<\/span> {<\/span>\n        <span class=\"hljs-built_in\">std<\/span>::promise&lt;T&gt; promise;\n\n        <span class=\"hljs-function\">async_task <span class=\"hljs-title\">get_return_object<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n            <span class=\"hljs-keyword\">return<\/span> async_task{ promise.get_future() };\n        }\n        <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::suspend_never <span class=\"hljs-title\">initial_suspend<\/span><span class=\"hljs-params\">()<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> {}; }\n        <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::suspend_always <span class=\"hljs-title\">final_suspend<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">noexcept<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> {}; }\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">return_value<\/span><span class=\"hljs-params\">(T value)<\/span> <\/span>{\n            promise.set_value(value);\n        }\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">unhandled_exception<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n            promise.set_exception(<span class=\"hljs-built_in\">std<\/span>::current_exception());\n        }\n    };\n\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">future<\/span>&lt;T&gt; <span class=\"hljs-built_in\">future<\/span>;\n    async_task(<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">future<\/span>&lt;T&gt;&amp;&amp; fut) : <span class=\"hljs-built_in\">future<\/span>(<span class=\"hljs-built_in\">std<\/span>::move(fut)) {}\n};\n\n<span class=\"hljs-keyword\">template<\/span> &lt;<span class=\"hljs-keyword\">typename<\/span> T&gt;\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title\">awaiter<\/span> {<\/span>\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">future<\/span>&lt;T&gt; <span class=\"hljs-built_in\">future<\/span>;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">await_ready<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">noexcept<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-built_in\">future<\/span>.wait_for(<span class=\"hljs-built_in\">std<\/span>::chrono::seconds(<span class=\"hljs-number\">0<\/span>)) == <span class=\"hljs-built_in\">std<\/span>::future_status::ready;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">await_suspend<\/span><span class=\"hljs-params\">(<span class=\"hljs-built_in\">std<\/span>::coroutine_handle&lt;&gt; handle)<\/span> <\/span>{\n        <span class=\"hljs-built_in\">std<\/span>::thread(&#91;<span class=\"hljs-keyword\">this<\/span>, handle]() <span class=\"hljs-keyword\">mutable<\/span> {\n            <span class=\"hljs-built_in\">future<\/span>.wait();\n            handle.resume();\n        }).detach();\n    }\n\n    <span class=\"hljs-function\">T <span class=\"hljs-title\">await_resume<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-built_in\">future<\/span>.get();\n    }\n};<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this example, <code>async_task<\/code> is a coroutine return type that wraps a <code>std::future<\/code>. The <code>promise_type<\/code> struct defines how the coroutine interacts with the promise and future. The <code>awaiter<\/code> struct provides the necessary methods to integrate <code>std::future<\/code> with coroutines.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Creating an Asynchronous Task<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Next, let&#8217;s create an asynchronous task using our awaiter.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-function\">async_task&lt;<span class=\"hljs-keyword\">int<\/span>&gt; <span class=\"hljs-title\">compute_async<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Computing asynchronously...\"<\/span> &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n    <span class=\"hljs-keyword\">co_return<\/span> <span class=\"hljs-number\">42<\/span>;\n}\n\n<span class=\"hljs-function\">async_task&lt;<span class=\"hljs-keyword\">void<\/span>&gt; <span class=\"hljs-title\">async_example<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">auto<\/span> result = <span class=\"hljs-keyword\">co_await<\/span> awaiter{ compute_async().<span class=\"hljs-built_in\">future<\/span> };\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Result: \"<\/span> &lt;&lt; result &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Here, <code>compute_async<\/code> is a coroutine that returns an <code>async_task&lt;int&gt;<\/code>. The <code>async_example<\/code> coroutine awaits the result of <code>compute_async<\/code> and prints it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Running the Coroutine<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, we need to run the coroutine.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">auto<\/span> example = async_example();\n    example.<span class=\"hljs-built_in\">future<\/span>.wait();\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">0<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This code creates an <code>async_example<\/code> coroutine and waits for its completion.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Handling Errors<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Handling errors in coroutines is crucial. The <code>promise_type<\/code> struct&#8217;s <code>unhandled_exception<\/code> method can capture exceptions thrown within the coroutine.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-keyword\">template<\/span> &lt;<span class=\"hljs-keyword\">typename<\/span> T&gt;\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title\">async_task<\/span> {<\/span>\n    <span class=\"hljs-class\"><span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title\">promise_type<\/span> {<\/span>\n        <span class=\"hljs-built_in\">std<\/span>::promise&lt;T&gt; promise;\n\n        <span class=\"hljs-function\">async_task <span class=\"hljs-title\">get_return_object<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n            <span class=\"hljs-keyword\">return<\/span> async_task{ promise.get_future() };\n        }\n        <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::suspend_never <span class=\"hljs-title\">initial_suspend<\/span><span class=\"hljs-params\">()<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> {}; }\n        <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::suspend_always <span class=\"hljs-title\">final_suspend<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">noexcept<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> {}; }\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">return_value<\/span><span class=\"hljs-params\">(T value)<\/span> <\/span>{\n            promise.set_value(value);\n        }\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">unhandled_exception<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n            promise.set_exception(<span class=\"hljs-built_in\">std<\/span>::current_exception());\n        }\n    };\n\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">future<\/span>&lt;T&gt; <span class=\"hljs-built_in\">future<\/span>;\n    async_task(<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">future<\/span>&lt;T&gt;&amp;&amp; fut) : <span class=\"hljs-built_in\">future<\/span>(<span class=\"hljs-built_in\">std<\/span>::move(fut)) {}\n};\n\n<span class=\"hljs-function\">async_task&lt;<span class=\"hljs-keyword\">int<\/span>&gt; <span class=\"hljs-title\">faulty_async<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-built_in\">std<\/span>::runtime_error(<span class=\"hljs-string\">\"Something went wrong\"<\/span>);\n    <span class=\"hljs-keyword\">co_return<\/span> <span class=\"hljs-number\">0<\/span>;\n}\n\n<span class=\"hljs-function\">async_task&lt;<span class=\"hljs-keyword\">void<\/span>&gt; <span class=\"hljs-title\">async_example<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">try<\/span> {\n        <span class=\"hljs-keyword\">auto<\/span> result = <span class=\"hljs-keyword\">co_await<\/span> awaiter{ faulty_async().<span class=\"hljs-built_in\">future<\/span> };\n        <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Result: \"<\/span> &lt;&lt; result &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n    } <span class=\"hljs-keyword\">catch<\/span> (<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-built_in\">std<\/span>::exception&amp; e) {\n        <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Error: \"<\/span> &lt;&lt; e.what() &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this example, <code>faulty_async<\/code> throws an exception, which is caught in <code>async_example<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Combining Coroutines with I\/O Operations<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Coroutines are particularly useful for I\/O operations, which often involve waiting. Let&#8217;s create an example that performs asynchronous file I\/O using coroutines.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Setting Up the Asynchronous I\/O<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;ll use <code>std::ifstream<\/code> to read a file asynchronously.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;fstream&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;string&gt;<\/span><\/span>\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title\">file_awaiter<\/span> {<\/span>\n    <span class=\"hljs-built_in\">std<\/span>::ifstream file;\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span> filename;\n\n    file_awaiter(<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&amp; filename) : filename(filename) {}\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">await_ready<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">noexcept<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">await_suspend<\/span><span class=\"hljs-params\">(<span class=\"hljs-built_in\">std<\/span>::coroutine_handle&lt;&gt; handle)<\/span> <\/span>{\n        <span class=\"hljs-built_in\">std<\/span>::thread(&#91;<span class=\"hljs-keyword\">this<\/span>, handle]() <span class=\"hljs-keyword\">mutable<\/span> {\n            file.open(filename);\n            handle.resume();\n        }).detach();\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::ifstream&amp; <span class=\"hljs-title\">await_resume<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> file;\n    }\n};<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The <code>file_awaiter<\/code> struct handles asynchronous file opening.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Creating a Coroutine for File I\/O<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Next, we&#8217;ll create a coroutine that uses <code>file_awaiter<\/code> to read from a file asynchronously.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-function\">async_task&lt;<span class=\"hljs-keyword\">void<\/span>&gt; <span class=\"hljs-title\">read_file_async<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&amp; filename)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">auto<\/span> file = <span class=\"hljs-keyword\">co_await<\/span> file_awaiter{ filename };\n    <span class=\"hljs-keyword\">if<\/span> (!file.is_open()) {\n        <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Failed to open file\"<\/span> &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n        <span class=\"hljs-keyword\">co_return<\/span>;\n    }\n\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span> line;\n    <span class=\"hljs-keyword\">while<\/span> (<span class=\"hljs-built_in\">std<\/span>::getline(file, line)) {\n        <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; line &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n    }\n    file.close();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this coroutine, <code>read_file_async<\/code>, we await the <code>file_awaiter<\/code> to open the file asynchronously and then read its contents.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Running the File I\/O Coroutine<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, let&#8217;s run our file I\/O coroutine.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">auto<\/span> example = read_file_async(<span class=\"hljs-string\">\"example.txt\"<\/span>);\n    example.<span class=\"hljs-built_in\">future<\/span>.wait();\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">0<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This code initiates the <code>read_file_async<\/code> coroutine and waits for it to complete.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Combining Multiple Coroutines<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Coroutines can be combined to perform complex asynchronous workflows. Let&#8217;s create an example where multiple coroutines work together to process data.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-function\">async_task&lt;<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&gt; <span class=\"hljs-title\">fetch_data_async<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Fetching data...\"<\/span> &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n    <span class=\"hljs-keyword\">co_return<\/span> <span class=\"hljs-string\">\"data\"<\/span>;\n}\n\n<span class=\"hljs-function\">async_task&lt;<span class=\"hljs-keyword\">void<\/span>&gt; <span class=\"hljs-title\">process_data_async<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&amp; data)<\/span> <\/span>{\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Processing data: \"<\/span> &lt;&lt; data &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n    <span class=\"hljs-keyword\">co_return<\/span>;\n}\n\n<span class=\"hljs-function\">async_task&lt;<span class=\"hljs-keyword\">void<\/span>&gt; <span class=\"hljs-title\">combined_example<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">auto<\/span> data = <span class=\"hljs-keyword\">co_await<\/span> awaiter{ fetch_data_async().<span class=\"hljs-built_in\">future<\/span> };\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">co_await<\/span> <span class=\"hljs-title\">process_data_async<\/span><span class=\"hljs-params\">(data)<\/span><\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this example, <code>fetch_data_async<\/code> fetches data asynchronously, and <code>process_data_async<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">processes the fetched data. The <code>combined_example<\/code> coroutine combines both tasks.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Advanced Coroutine Features<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">C++ Coroutines offer several advanced features that can further enhance asynchronous programming.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Custom Awaitable Types<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You can create custom awaitable types to extend the capabilities of coroutines.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-keyword\">template<\/span> &lt;<span class=\"hljs-keyword\">typename<\/span> T&gt;\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title\">custom_awaitable<\/span> {<\/span>\n    T value;\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">await_ready<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">noexcept<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">true<\/span>; }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">await_suspend<\/span><span class=\"hljs-params\">(<span class=\"hljs-built_in\">std<\/span>::coroutine_handle&lt;&gt;)<\/span> <\/span>{}\n    <span class=\"hljs-function\">T <span class=\"hljs-title\">await_resume<\/span><span class=\"hljs-params\">()<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> value; }\n};\n\n<span class=\"hljs-function\">async_task&lt;<span class=\"hljs-keyword\">void<\/span>&gt; <span class=\"hljs-title\">custom_awaitable_example<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">auto<\/span> result = <span class=\"hljs-keyword\">co_await<\/span> custom_awaitable&lt;<span class=\"hljs-keyword\">int<\/span>&gt;{ <span class=\"hljs-number\">10<\/span> };\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Custom awaitable result: \"<\/span> &lt;&lt; result &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this example, <code>custom_awaitable<\/code> is a simple awaitable type that immediately returns a value.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Coroutine Traits<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You can define custom coroutine traits to control how coroutines are created and managed.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-keyword\">template<\/span> &lt;<span class=\"hljs-keyword\">typename<\/span> PromiseType&gt;\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title\">custom_allocator<\/span> {<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span>* <span class=\"hljs-title\">allocate<\/span><span class=\"hljs-params\">(<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-keyword\">size_t<\/span> size)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> ::<span class=\"hljs-keyword\">operator<\/span> <span class=\"hljs-keyword\">new<\/span>(size);\n    }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">deallocate<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">void<\/span>* ptr, <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-keyword\">size_t<\/span> size)<\/span> <\/span>{\n        ::<span class=\"hljs-function\"><span class=\"hljs-keyword\">operator<\/span> <span class=\"hljs-title\">delete<\/span><span class=\"hljs-params\">(ptr, size)<\/span><\/span>;\n    }\n};\n\n<span class=\"hljs-keyword\">template<\/span> &lt;<span class=\"hljs-keyword\">typename<\/span> T&gt;\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title\">custom_task<\/span> {<\/span>\n    <span class=\"hljs-class\"><span class=\"hljs-keyword\">struct<\/span> <span class=\"hljs-title\">promise_type<\/span> {<\/span>\n        <span class=\"hljs-function\">custom_task <span class=\"hljs-title\">get_return_object<\/span><span class=\"hljs-params\">()<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> {}; }\n        <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::suspend_never <span class=\"hljs-title\">initial_suspend<\/span><span class=\"hljs-params\">()<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> {}; }\n        <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::suspend_never <span class=\"hljs-title\">final_suspend<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">noexcept<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> {}; }\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">return_void<\/span><span class=\"hljs-params\">()<\/span> <\/span>{}\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">unhandled_exception<\/span><span class=\"hljs-params\">()<\/span> <\/span>{ <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">terminate<\/span>(); }\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span>* <span class=\"hljs-keyword\">operator<\/span> <span class=\"hljs-title\">new<\/span><span class=\"hljs-params\">(<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-keyword\">size_t<\/span> size)<\/span> <\/span>{\n            <span class=\"hljs-keyword\">return<\/span> custom_allocator&lt;promise_type&gt;{}.allocate(size);\n        }\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-keyword\">operator<\/span> <span class=\"hljs-title\">delete<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">void<\/span>* ptr, <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-keyword\">size_t<\/span> size)<\/span> <\/span>{\n            custom_allocator&lt;promise_type&gt;{}.deallocate(ptr, size);\n        }\n    };\n};\n\n<span class=\"hljs-function\">custom_task&lt;<span class=\"hljs-keyword\">void<\/span>&gt; <span class=\"hljs-title\">custom_task_example<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Using custom task\"<\/span> &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n    <span class=\"hljs-keyword\">co_return<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this example, <code>custom_task<\/code> uses a custom allocator for coroutine memory management.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Best Practices for Using Coroutines<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Here are some best practices to keep in mind when using coroutines in C++:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Understand the Lifecycle<\/strong>: Be aware of how coroutines are created, suspended, and destroyed. Properly managing coroutine state is crucial for preventing resource leaks and undefined behavior.<\/li>\n\n\n\n<li><strong>Handle Exceptions<\/strong>: Always handle exceptions within coroutines to ensure they don&#8217;t cause crashes or unexpected behavior.<\/li>\n\n\n\n<li><strong>Use Appropriate Return Types<\/strong>: Choose the right return types for your coroutines based on the tasks they perform. For asynchronous tasks, consider using <code>std::future<\/code> or custom awaitable types.<\/li>\n\n\n\n<li><strong>Minimize Blocking Operations<\/strong>: Coroutines are designed to be non-blocking. Avoid using blocking operations within coroutines to maintain their asynchronous nature.<\/li>\n\n\n\n<li><strong>Optimize for Performance<\/strong>: Coroutines can introduce overhead due to context switching. Optimize your coroutines and avoid unnecessary suspensions to improve performance.<\/li>\n\n\n\n<li><strong>Leverage Libraries<\/strong>: Consider using libraries like Boost.Asio or cppcoro, which provide additional utilities and abstractions for working with coroutines.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">C++ Coroutines offer a powerful mechanism for handling asynchronous tasks. By understanding the fundamental concepts, syntax, and best practices, you can effectively integrate coroutines into your C++ projects. This tutorial covered the basics of coroutines, including creating simple coroutines, handling asynchronous tasks, combining coroutines, and using advanced features.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Coroutines can greatly simplify asynchronous programming, making your code more readable and maintainable. As you gain experience with coroutines, you&#8217;ll discover even more ways to leverage their power to handle complex asynchronous workflows.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>C++ Coroutines, introduced in C++20, offer a powerful way to handle asynchronous tasks. This tutorial aims to guide you through the essentials of using C++ Coroutines for asynchronous programming. We will cover the fundamental concepts, the necessary syntax, and practical examples to ensure you understand how to effectively implement coroutines in your projects. The target [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[9,4],"tags":[],"class_list":["post-2131","post","type-post","status-publish","format-standard","category-cplusplus","category-programming-languages","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to Use C++ Coroutines for Asynchronous Tasks<\/title>\n<meta name=\"description\" content=\"A coroutine is a function that can suspend its execution to be resumed later. Unlike regular functions, which run from start to finish\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Use C++ Coroutines for Asynchronous Tasks\" \/>\n<meta property=\"og:description\" content=\"A coroutine is a function that can suspend its execution to be resumed later. Unlike regular functions, which run from start to finish\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/\" \/>\n<meta property=\"article:published_time\" content=\"2024-07-20T20:47:55+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-07-20T20:47:58+00:00\" \/>\n<meta name=\"author\" content=\"w3compadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"w3compadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-use-cpp-coroutines-for-asynchronous-tasks\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-use-cpp-coroutines-for-asynchronous-tasks\\\/\"},\"author\":{\"name\":\"w3compadmin\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"headline\":\"How to Use C++ Coroutines for Asynchronous Tasks\",\"datePublished\":\"2024-07-20T20:47:55+00:00\",\"dateModified\":\"2024-07-20T20:47:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-use-cpp-coroutines-for-asynchronous-tasks\\\/\"},\"wordCount\":934,\"articleSection\":[\"C++\",\"Programming Languages\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-use-cpp-coroutines-for-asynchronous-tasks\\\/\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-use-cpp-coroutines-for-asynchronous-tasks\\\/\",\"name\":\"How to Use C++ Coroutines for Asynchronous Tasks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\"},\"datePublished\":\"2024-07-20T20:47:55+00:00\",\"dateModified\":\"2024-07-20T20:47:58+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"description\":\"A coroutine is a function that can suspend its execution to be resumed later. Unlike regular functions, which run from start to finish\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-use-cpp-coroutines-for-asynchronous-tasks\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-use-cpp-coroutines-for-asynchronous-tasks\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-use-cpp-coroutines-for-asynchronous-tasks\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Articles Home\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming Languages\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"How to Use C++ Coroutines for Asynchronous Tasks\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\",\"name\":\"Developer Articles Hub\",\"description\":\"\",\"alternateName\":\"Developer Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\",\"name\":\"w3compadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"contentUrl\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"caption\":\"w3compadmin\"},\"sameAs\":[\"http:\\\/\\\/w3computing.com\\\/articles\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Use C++ Coroutines for Asynchronous Tasks","description":"A coroutine is a function that can suspend its execution to be resumed later. Unlike regular functions, which run from start to finish","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/","og_locale":"en_US","og_type":"article","og_title":"How to Use C++ Coroutines for Asynchronous Tasks","og_description":"A coroutine is a function that can suspend its execution to be resumed later. Unlike regular functions, which run from start to finish","og_url":"https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/","article_published_time":"2024-07-20T20:47:55+00:00","article_modified_time":"2024-07-20T20:47:58+00:00","author":"w3compadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"w3compadmin","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/#article","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/"},"author":{"name":"w3compadmin","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"headline":"How to Use C++ Coroutines for Asynchronous Tasks","datePublished":"2024-07-20T20:47:55+00:00","dateModified":"2024-07-20T20:47:58+00:00","mainEntityOfPage":{"@id":"https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/"},"wordCount":934,"articleSection":["C++","Programming Languages"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/","url":"https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/","name":"How to Use C++ Coroutines for Asynchronous Tasks","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/#website"},"datePublished":"2024-07-20T20:47:55+00:00","dateModified":"2024-07-20T20:47:58+00:00","author":{"@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"description":"A coroutine is a function that can suspend its execution to be resumed later. Unlike regular functions, which run from start to finish","breadcrumb":{"@id":"https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.w3computing.com\/articles\/how-to-use-cpp-coroutines-for-asynchronous-tasks\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Articles Home","item":"https:\/\/www.w3computing.com\/articles\/"},{"@type":"ListItem","position":2,"name":"Programming Languages","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/"},{"@type":"ListItem","position":3,"name":"How to Use C++ Coroutines for Asynchronous Tasks"}]},{"@type":"WebSite","@id":"https:\/\/www.w3computing.com\/articles\/#website","url":"https:\/\/www.w3computing.com\/articles\/","name":"Developer Articles Hub","description":"","alternateName":"Developer Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.w3computing.com\/articles\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561","name":"w3compadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","url":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","contentUrl":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","caption":"w3compadmin"},"sameAs":["http:\/\/w3computing.com\/articles"]}]}},"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":"w3compadmin","author_link":"https:\/\/www.w3computing.com\/articles\/author\/w3compadmin\/"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/2131","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/comments?post=2131"}],"version-history":[{"count":2,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/2131\/revisions"}],"predecessor-version":[{"id":2133,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/2131\/revisions\/2133"}],"wp:attachment":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/media?parent=2131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/categories?post=2131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/tags?post=2131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}