{"id":10026,"date":"2024-09-16T09:29:02","date_gmt":"2024-09-16T09:29:02","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=10026"},"modified":"2025-07-03T15:36:45","modified_gmt":"2025-07-03T15:36:45","slug":"an-overview-of-c26-concurrency","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/an-overview-of-c26-concurrency\/","title":{"rendered":"An Overview of C++26: Concurrency"},"content":{"rendered":"\n<p> Today, I will finish my overview of C++26 and write about concurrency.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1030\" height=\"450\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/09\/TimelineCpp26Library-1030x450.png\" alt=\"\" class=\"wp-image-10028\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/09\/TimelineCpp26Library-1030x450.png 1030w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/09\/TimelineCpp26Library-300x131.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/09\/TimelineCpp26Library-768x335.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/09\/TimelineCpp26Library-705x308.png 705w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/09\/TimelineCpp26Library.png 1180w\" sizes=\"auto, (max-width: 1030px) 100vw, 1030px\" \/><\/figure>\n\n\n\n<p>There are still two library features left before I jump into the concurrency: saturation arithmetic and debugging support. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Saturation Arithmetic <\/h2>\n\n\n\n<p><em><strong>Saturation arithmetic<\/strong> is a version of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Arithmetic\">arithmetic<\/a> in which all operations, such as <a href=\"https:\/\/en.wikipedia.org\/wiki\/Addition\">addition<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Multiplication\">multiplication<\/a>, are limited to a fixed range between a minimum and maximum value.<\/em><\/p>\n\n\n\n<p><em>If the result of an operation is greater than the maximum, it is set (&#8220;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Clamping_(graphics)\">clamped<\/a>&#8220;) to the maximum; if it is below the minimum, it is clamped to the minimum. The name comes from how the value becomes &#8220;saturated&#8221; once it reaches the extreme values; further additions to a maximum or subtractions from a minimum will not change the result.<\/em> (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Saturation_arithmetic\">https:\/\/en.wikipedia.org\/wiki\/Saturation_arithmetic)<\/a><\/p>\n\n\n\n<p>C++26 introduced a set of saturating arithmetic operations: <strong>addition, subtraction, multiplication, division, and saturate cast<\/strong>. If the specified integral type <code>T <\/code>cannot represent the result of the operation, the result is instead <code>std::numeric_limits::min&lt;T&gt;()<\/code> or<code> std::numeric_limits::max&lt;T&gt;() <\/code>(whichever is closer).<\/p>\n\n\n\n<p><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/numeric\/add_sat\">cppreference.com<\/a> has a nice example with an explanation to<code> std::add_sat<\/code>.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #009999\">#include &lt;climits&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;limits&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;numeric&gt;<\/span>\n \nstatic_assert(CHAR_BIT <span style=\"color: #555555\">==<\/span> <span style=\"color: #FF6600\">8<\/span>);\nstatic_assert(UCHAR_MAX <span style=\"color: #555555\">==<\/span> <span style=\"color: #FF6600\">255<\/span>);\n \n<span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>()\n{\n    constexpr <span style=\"color: #007788; font-weight: bold\">int<\/span> a <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>add_sat(<span style=\"color: #FF6600\">3<\/span>, <span style=\"color: #FF6600\">4<\/span>); <span style=\"color: #0099FF; font-style: italic\">\/\/ no saturation occurs, T = int<\/span>\n    static_assert(a <span style=\"color: #555555\">==<\/span> <span style=\"color: #FF6600\">7<\/span>);\n \n    constexpr <span style=\"color: #007788; font-weight: bold\">unsigned<\/span> <span style=\"color: #007788; font-weight: bold\">char<\/span> b <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>add_sat<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">unsigned<\/span> <span style=\"color: #007788; font-weight: bold\">char<\/span><span style=\"color: #555555\">&gt;<\/span>(UCHAR_MAX, <span style=\"color: #FF6600\">4<\/span>); <span style=\"color: #0099FF; font-style: italic\">\/\/ saturated<\/span>\n    static_assert(b <span style=\"color: #555555\">==<\/span> UCHAR_MAX);\n \n    constexpr <span style=\"color: #007788; font-weight: bold\">unsigned<\/span> <span style=\"color: #007788; font-weight: bold\">char<\/span> c <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>add_sat(UCHAR_MAX, <span style=\"color: #FF6600\">4<\/span>); <span style=\"color: #0099FF; font-style: italic\">\/\/ not saturated, T = int<\/span>\n        <span style=\"color: #0099FF; font-style: italic\">\/\/ add_sat(int, int) returns int tmp == 259,<\/span>\n        <span style=\"color: #0099FF; font-style: italic\">\/\/ then assignment truncates 259 % 256 == 3<\/span>\n    static_assert(c <span style=\"color: #555555\">==<\/span> <span style=\"color: #FF6600\">3<\/span>);\n \n<span style=\"color: #0099FF; font-style: italic\">\/\/  unsigned char d = std::add_sat(252, c); \/\/ Error: inconsistent deductions for T<\/span>\n \n    constexpr <span style=\"color: #007788; font-weight: bold\">unsigned<\/span> <span style=\"color: #007788; font-weight: bold\">char<\/span> e <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>add_sat<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">unsigned<\/span> <span style=\"color: #007788; font-weight: bold\">char<\/span><span style=\"color: #555555\">&gt;<\/span>(<span style=\"color: #FF6600\">251<\/span>, a); <span style=\"color: #0099FF; font-style: italic\">\/\/ saturated<\/span>\n    static_assert(e <span style=\"color: #555555\">==<\/span> UCHAR_MAX);\n        <span style=\"color: #0099FF; font-style: italic\">\/\/ 251 is of type T = unsigned char, `a` is converted to unsigned char value;<\/span>\n        <span style=\"color: #0099FF; font-style: italic\">\/\/ might yield an int -&gt; unsigned char conversion warning for `a`<\/span>\n \n    constexpr <span style=\"color: #007788; font-weight: bold\">signed<\/span> <span style=\"color: #007788; font-weight: bold\">char<\/span> f <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>add_sat<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">signed<\/span> <span style=\"color: #007788; font-weight: bold\">char<\/span><span style=\"color: #555555\">&gt;<\/span>(<span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">123<\/span>, <span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">3<\/span>); <span style=\"color: #0099FF; font-style: italic\">\/\/ not saturated<\/span>\n    static_assert(f <span style=\"color: #555555\">==<\/span> <span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">126<\/span>);\n \n    constexpr <span style=\"color: #007788; font-weight: bold\">signed<\/span> <span style=\"color: #007788; font-weight: bold\">char<\/span> g <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>add_sat<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">signed<\/span> <span style=\"color: #007788; font-weight: bold\">char<\/span><span style=\"color: #555555\">&gt;<\/span>(<span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">123<\/span>, <span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">13<\/span>); <span style=\"color: #0099FF; font-style: italic\">\/\/ saturated<\/span>\n    static_assert(g <span style=\"color: #555555\">==<\/span> std<span style=\"color: #555555\">::<\/span>numeric_limits<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">signed<\/span> <span style=\"color: #007788; font-weight: bold\">char<\/span><span style=\"color: #555555\">&gt;::<\/span>min()); <span style=\"color: #0099FF; font-style: italic\">\/\/ g == -128<\/span>\n}\n<\/pre><\/div>\n\n\n\n<p>T is the type of both function arguments:   <\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #006699; font-weight: bold\">template<\/span><span style=\"color: #555555\">&lt;<\/span> <span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">T<\/span> <span style=\"color: #555555\">&gt;<\/span>\nconstexpr T add_sat( T x, T y ) noexcept;\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"> debugging Support <\/h2>\n\n\n\n<p>C++26 has three functions for debugging. <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>std::breakpoint<\/code>: pauses the running program when called and passes the control to the debugger<\/li>\n\n\n\n<li><code>std::breakpoint_if_debugging:<\/code> calls<code> std::breakpoint <\/code>if s<code>td::is_debugger_present <\/code>returns <code>true<\/code><\/li>\n\n\n\n<li><code>std::is_debugger_present:<\/code> checks whether a program is running under the control of a debugger<\/li>\n<\/ul>\n\n\n\n<p> This was the first overview of the C++26 library. Let&#8217;s continue with the Concurrency.<\/p>\n\n\n\n<p> Concurrency in C++26 has one dominant feature:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><code>std::execution<\/code> <\/h2>\n\n\n\n<p><strong><code>std::execution<\/code><\/strong>, previously known as executors or Senders\/Receivers, provides \u201c<em>a Standard C++ framework for managing asynchronous execution on generic execution resources<\/em>\u201c. (<a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2024\/p2300r10.html\">P2300R10<\/a>). It has three key abstractions: schedulers, senders, and receivers, and a set of customizable asynchronous algorithms.<\/p>\n\n\n\n<p> The &#8220;Hello word&#8221; program of the proposal <a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2024\/p2300r10.html\">P2300R10<\/a> shows them.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #006699; font-weight: bold\">using<\/span> <span style=\"color: #006699; font-weight: bold\">namespace<\/span> std<span style=\"color: #555555\">::<\/span>execution;\n\nscheduler <span style=\"color: #006699; font-weight: bold\">auto<\/span> sch <span style=\"color: #555555\">=<\/span> thread_pool.scheduler();                                 <span style=\"color: #0099FF; font-style: italic\">\/\/ 1<\/span>\n\nsender <span style=\"color: #006699; font-weight: bold\">auto<\/span> begin <span style=\"color: #555555\">=<\/span> schedule(sch);                                            <span style=\"color: #0099FF; font-style: italic\">\/\/ 2<\/span>\nsender <span style=\"color: #006699; font-weight: bold\">auto<\/span> hi <span style=\"color: #555555\">=<\/span> then(begin, []{                                              <span style=\"color: #0099FF; font-style: italic\">\/\/ 3<\/span>\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;Hello world! Have an int.&quot;<\/span>;                                 <span style=\"color: #0099FF; font-style: italic\">\/\/ 3<\/span>\n    <span style=\"color: #006699; font-weight: bold\">return<\/span> <span style=\"color: #FF6600\">13<\/span>;                                                                <span style=\"color: #0099FF; font-style: italic\">\/\/ 3<\/span>\n});                                                                           <span style=\"color: #0099FF; font-style: italic\">\/\/ 3<\/span>\nsender <span style=\"color: #006699; font-weight: bold\">auto<\/span> add_42 <span style=\"color: #555555\">=<\/span> then(hi, [](<span style=\"color: #007788; font-weight: bold\">int<\/span> arg) { <span style=\"color: #006699; font-weight: bold\">return<\/span> arg <span style=\"color: #555555\">+<\/span> <span style=\"color: #FF6600\">42<\/span>; });              <span style=\"color: #0099FF; font-style: italic\">\/\/ 4<\/span>\n\n<span style=\"color: #006699; font-weight: bold\">auto<\/span> [i] <span style=\"color: #555555\">=<\/span> this_thread<span style=\"color: #555555\">::<\/span>sync_wait(add_42).value();  \n<\/pre><\/div>\n\n\n\n<p>The explanation of the example is so good that I will directly quote them here:<\/p>\n\n\n\n<p><em>This example demonstrates the basics of schedulers, senders, and receivers:<\/em><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><em>First we need to get a scheduler from somewhere, such as a thread pool. A scheduler is a lightweight handle to an execution resource.<\/em><\/li>\n\n\n\n<li><em>To start a chain of work on a scheduler, we call <a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2024\/p2300r10.html#design-sender-factory-schedule\">\u00a7\u202f4.19.1 execution::schedule<\/a>, which returns a sender that completes on the scheduler. A sender describes asynchronous work and sends a signal (value, error, or stopped) to some recipient(s) when that work completes.<\/em><\/li>\n\n\n\n<li><em>We use sender algorithms to produce senders and compose asynchronous work. <a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2024\/p2300r10.html#design-sender-adaptor-then\">\u00a7\u202f4.20.2 execution::then<\/a> is a sender adaptor that takes an input sender and a <code>std::invocable<\/code>, and calls the <code>std::invocable<\/code> on the signal sent by the input sender. The sender returned by <code>then<\/code> sends the result of that invocation. In this case, the input sender came from <code>schedule<\/code>, so its <code>void<\/code>, meaning it won\u2019t send us a value, so our <code>std::invocable<\/code> takes no parameters. But we return an <code>int<\/code>, which will be sent to the next recipient.<\/em><\/li>\n\n\n\n<li><em>Now, we add another operation to the chain, again using <a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2024\/p2300r10.html#design-sender-adaptor-then\">\u00a7\u202f4.20.2 execution::then<\/a>. This time, we get sent a value &#8211; the <code>int<\/code> from the previous step. We add <code>42<\/code> to it, and then return the result.<\/em><\/li>\n\n\n\n<li><em>Finally, we\u2019re ready to submit the entire asynchronous pipeline and wait for its completion. Everything up until this point has been completely asynchronous; the work may not have even started yet. To ensure the work has started and then block pending its completion, we use <a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2024\/p2300r10.html#design-sender-consumer-sync_wait\">\u00a7\u202f4.21.1 this_thread::sync_wait<\/a>, which will either return a <code>std::optional&lt;std::tuple&lt;...&gt;&gt;<\/code> with the value sent by the last sender, or an empty <code>std::optional<\/code> if the last sender sent a stopped signal, or it throws an exception if the last sender sent an error.<\/em><\/li>\n<\/ol>\n\n\n\n<p>The proposal provides further excellent examples. I will analyze them in upcoming posts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Read-Copy Update (RCU) and Hazard Pointers<\/h2>\n\n\n\n<p>Read-Copy Update and Hazard Pointers solve the classical problem of lock-free data structures, such as a lock-free stack: When can a thread safely delete a data structure node while other threads can use this node simultaneously?<\/p>\n\n\n\n<p>Those structures are too complex and require too much information to be adequately discussed in an overview article.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"> What&#8217;s next?<\/h2>\n\n\n\n<p>In the next post about C++26, I will change my focus and dive into the details.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, I will finish my overview of C++26 and write about concurrency. There are still two library features left before I jump into the concurrency: saturation arithmetic and debugging support. Saturation Arithmetic Saturation arithmetic is a version of arithmetic in which all operations, such as addition and multiplication, are limited to a fixed range between [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":10028,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[559],"tags":[],"class_list":["post-10026","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c26-blog"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10026","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=10026"}],"version-history":[{"count":26,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10026\/revisions"}],"predecessor-version":[{"id":10848,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10026\/revisions\/10848"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/10028"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=10026"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=10026"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=10026"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}