{"id":5459,"date":"2018-06-19T05:42:42","date_gmt":"2018-06-19T05:42:42","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-concurrency-and-lock-free-programming\/"},"modified":"2023-06-26T11:49:06","modified_gmt":"2023-06-26T11:49:06","slug":"c-core-guidelines-concurrency-and-lock-free-programming","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-concurrency-and-lock-free-programming\/","title":{"rendered":"C++ Core Guidelines: Concurrency and lock-free Programming"},"content":{"rendered":"<p>Today, I will finish the rules for concurrency and continue directly with lock-free programming. Yes, you have read it correctly: lock-free programming.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5456\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/fear-cat.jpg\" alt=\"fear cat\" width=\"600\" height=\"400\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/fear-cat.jpg 1920w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/fear-cat-300x200.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/fear-cat-1024x683.jpg 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/fear-cat-768x512.jpg 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/fear-cat-1536x1024.jpg 1536w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>Before I write about lock-free programming in particular, here are the three last rules to concurrency.<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rconc-time\">CP.43: Minimize time spent in a critical section<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rconc-name\">CP.44: Remember to name your <code class=\"highlighter-rouge no-highlight\">lock_guard<\/code>s and <code class=\"highlighter-rouge no-highlight\">unique_lock<\/code>s<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rconc-mutex\">CP.50: Define a <code class=\"highlighter-rouge no-highlight\">mutex<\/code> together with the data it guards. Use <code class=\"highlighter-rouge no-highlight\">synchronized_value&lt;T&gt;<\/code> where possible<\/a><\/li>\n<\/ul>\n<p>I make it short because these rules are quite obvious.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rconc-time\">CP.43: Minimize time spent in a critical section<\/a><\/h3>\n<p>The less time your lock a mutex, the more time other threads can run. Have a look at the notification of a condition variable. If you want to see the entire program, read my previous post <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-be-aware-of-the-traps-of-condition-variables\">C++ Core Guidelines: Be Aware of the Traps of Condition Variables<\/a>.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">setDataReady<\/span>(){\r\n    std<span style=\"color: #555555;\">::<\/span>lock_guard<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>mutex<span style=\"color: #555555;\">&gt;<\/span> lck(mutex_);\r\n    dataReady <span style=\"color: #555555;\">=<\/span> <span style=\"color: #336666;\">true<\/span>;                                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1) <\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Data prepared\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; \r\n    condVar.notify_one(); \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The Mutex <span style=\"font-family: courier new, courier;\">mutex_<\/span> is locked at the beginning and unlocked at the end of the function. This is not necessary. Only the expression<span style=\"font-family: courier new, courier;\"> dataReady = true<\/span> (1) has to be protected.<\/p>\n<p>First,<span style=\"font-family: courier new, courier;\"> std::cout<\/span> is thread-safe. The C++11 standard guarantees that each character is written in an atomic step and the correct sequence. Second, the notification<span style=\"font-family: courier new, courier;\"> condVar.notify_one()<\/span> is thread-safe.<\/p>\n<p>Here is the improved version of the function <span style=\"font-family: courier new, courier;\">setDataReady:<\/span><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">setDataReady<\/span>(){\r\n    {  <span style=\"color: #0099ff; font-style: italic;\">\/\/ Don't remove because of the lifetime of the mutex (1)<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>lock_guard<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>mutex<span style=\"color: #555555;\">&gt;<\/span> lck(mutex_);\r\n        dataReady <span style=\"color: #555555;\">=<\/span> <span style=\"color: #336666;\">true<\/span>;\r\n    }                  <span style=\"color: #0099ff; font-style: italic;\">                                     (2)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Data prepared\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    condVar.notify_one();    <span style=\"color: #0099ff; font-style: italic;\">           <\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>When I teach this rule in my classes to concurrency, often a question arises:&nbsp; Should you document this artificial scope for limiting the lifetime of the <span style=\"font-family: courier new, courier;\">std::lock_guard<\/span> and, therefore, the lifetime of the <span style=\"font-family: courier new, courier;\">std::mutex <\/span>(line (1) and (2))? Most of my students, including me, add a comment to this artificial scope. If not, the maintainer of your code may not be aware that the curly braces in line (1) and line (2) are necessary for controlling the lifetime of the mutex. Ultimately, your maintainer will remove the artificial scope because it seems superfluous, and your code uses the first variant.<\/p>\n<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rconc-name\">CP.44: Remember to name your <code class=\"highlighter-rouge no-highlight\">lock_guard<\/code>s and <code class=\"highlighter-rouge no-highlight\">unique_lock<\/code>s<\/a><\/h3>\n<p>I was a little astonished to read this rule. Here is an example from the guidelines:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">unique_lock<span style=\"color: #555555;\">&lt;<\/span>mutex<span style=\"color: #555555;\">&gt;<\/span>(m1);\r\nlock_guard<span style=\"color: #555555;\">&lt;<\/span>mutex<span style=\"color: #555555;\">&gt;<\/span> {m2};\r\nlock(m1, m2);\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The <span style=\"font-family: courier new, courier;\">unique_lock<\/span> and <span style=\"font-family: courier new, courier;\">lock_guard<\/span> are just temporaries that are created and immediately destroyed. The<span style=\"font-family: courier new, courier;\"> std::lock_guard<\/span> or <span style=\"font-family: courier new, courier;\">std::unique_lock<\/span> locks its mutex and its constructor and unlocks it in its destructor. This pattern is called RAII. Read the details here:<a href=\"https:\/\/www.modernescpp.com\/index.php\/garbage-collectio-no-thanks\"> Garbage Collection: No Thanks<\/a>.<\/p>\n<p>My small example shows only the conceptual behavior of a <span style=\"font-family: courier new, courier;\">std::lock_guard. <\/span>Its big brother<span style=\"font-family: courier new, courier;\"><\/span><span style=\"font-family: courier new, courier;\">std::unique_lock<\/span> supports more operations<span style=\"font-family: courier new, courier;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ myGuard.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;mutex&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyGuard<\/span>{\r\n  T<span style=\"color: #555555;\">&amp;<\/span> myMutex;\r\n  <span style=\"color: #9999ff;\">public:<\/span>\r\n    MyGuard(T<span style=\"color: #555555;\">&amp;<\/span> m)<span style=\"color: #555555;\">:<\/span>myMutex(m){\r\n      myMutex.lock();\r\n\t  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"lock\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    }\r\n    <span style=\"color: #555555;\">~<\/span>MyGuard(){\r\n\t  myMutex.unlock();\r\n      std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"unlock\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    }\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\t\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\t\r\n  std<span style=\"color: #555555;\">::<\/span>mutex m;\r\n  MyGuard<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>mutex<span style=\"color: #555555;\">&gt;<\/span> {m};                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"CRITICAL SECTION\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n}                                                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: courier new, courier;\">MyGuard<\/span> calls lock and unlock in its constructor and its destructor. Because of the temporary, the call to the constructor and destructor happens in line (1). In particular, this means that the call of the destructor happens at line (1) and not, as usual, in line (3). Consequently, the critical section in line (2) is executed without synchronization.<\/p>\n<p>This execution of the program shows that the output of &#8220;<span style=\"font-family: courier new, courier;\">unlock<\/span>&#8221; happens before the output of &#8220;<span style=\"font-family: courier new, courier;\">CRITICAL SECTION<\/span>&#8220;.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5457\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/myGuard.png\" alt=\"myGuard\" width=\"300\" height=\"193\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/myGuard.png 555w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/myGuard-300x192.png 300w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rconc-mutex\">CP.50: Define a <code class=\"highlighter-rouge no-highlight\">mutex<\/code> together with the data it guards. Use <code class=\"highlighter-rouge no-highlight\">synchronized_value&lt;T&gt;<\/code> where possible<\/a><\/h3>\n<p>The central idea is to put your mutex into the data you want to protect. With already standardized C++ it looks like this:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">struct<\/span> Record {\r\n    std<span style=\"color: #555555;\">::<\/span>mutex m;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ take this mutex before accessing other members<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>With an upcoming standard, it may look like this because <span style=\"font-family: courier new, courier;\">synchronized_value&lt;T&gt;<\/span> is not part of the current C++ standard, but it may become part of an upcoming standard.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyClass<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">struct<\/span> DataRecord {\r\n       <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n    };\r\n    synchronized_value<span style=\"color: #555555;\">&lt;<\/span>DataRecord<span style=\"color: #555555;\">&gt;<\/span> data; <span style=\"color: #0099ff; font-style: italic;\">\/\/ Protect the data with a mutex<\/span>\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>According to proposal <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2014\/n4033.html\">N4033<\/a> from Anthony Williams: &#8220;<em>The basic idea is that <code>synchronized_value&lt;T&gt;<\/code> stores a value of type <code>T<\/code> and a mutex. It then exposes a pointer interface, such that dereferencing the pointer yields a special wrapper type that holds a lock on the mutex, and that can be implicitly converted to <code>T<\/code> for reading, and which forwards any values assigned to the assignment operator of the underlying <code>T<\/code> for writing<\/em>.&#8221;<\/p>\n<p>This means that the operation on s in the following code snippet is thread-safe.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">synchronized_value<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&gt;<\/span> s;\r\n\r\nstd<span style=\"color: #555555;\">::<\/span>string readValue()\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #555555;\">*<\/span>s;\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> setValue(std<span style=\"color: #555555;\">::<\/span>string <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> newVal)\r\n{\r\n    <span style=\"color: #555555;\">*<\/span>s<span style=\"color: #555555;\">=<\/span>newVal;\r\n}\r\n \r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> appendToValue(std<span style=\"color: #555555;\">::<\/span>string <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> extra)\r\n{\r\n    s<span style=\"color: #555555;\">-&gt;<\/span>append(extra);\r\n}\r\n<\/pre>\n<\/div>\n<p><span style=\"font-family: courier new, courier;\"><\/span><\/p>\n<p>Now as announced, to something completely different: lock-free programming.<\/p>\n<h2>Lock-free programming<\/h2>\n<p>First, let me state the most crucial meta-rule to lock-free programming.<\/p>\n<h3>Don&#8217;t program lock-free<\/h3>\n<p>Sure, you don&#8217;t believe me, but based on my experience giving many concurrency classes and workshops, this is<strong> my<\/strong> first rule. Honestly, I agree with many of the most appreciated C++ experts worldwide. Here are the critical statements and cites from their talks:<\/p>\n<ul>\n<li><strong>Herb Sutter<\/strong>: Lock-free programming is like playing with knives.<\/li>\n<li><strong>Anthony Williams<\/strong>: &#8220;<em>Lock-free programming is about how to shoot yourself in the foot.<\/em>&#8220;<\/li>\n<li><strong>Tony Van Eerd<\/strong>: &#8220;<em>Lock-free coding is the last thing you want to do<\/em>.&#8221;<\/li>\n<li><strong>Fedor Pikus<\/strong>: &#8220;<em>Writing correct lock-free programs is even harder.<\/em>&#8220;<\/li>\n<li><strong>Harald B\u00f6hm<\/strong>: &#8220;<em>The rules are not obvious.<\/em>&#8220;<\/li>\n<\/ul>\n<p>Here is a picture of the statements and cites:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5458\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/lockFree.png\" alt=\"lockFree\" width=\"700\" height=\"455\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/lockFree.png 990w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/lockFree-300x195.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/lockFree-768x500.png 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<p>You still don&#8217;t believe me? With C++11, the memory order <span style=\"font-family: 'courier new', courier;\">std::memory_order_consume<\/span> was defined. Seven years later, the official wording is: &#8220;<em>The specification of release-consume ordering is being revised, and the use of <code>memory_order_consume<\/code> is temporarily discouraged.<\/em>&#8221; (<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/atomic\/memory_order\">memory_order<\/a>)<\/p>\n<p>If you know what you do, think about the <a href=\"https:\/\/www.modernescpp.com\/index.php\/aba-a-is-not-the-same-as-a\">ABA<\/a>&nbsp;problem in the guidelines CP.100.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rconc-lockfree\">CP.100: Don\u2019t use lock-free programming unless you absolutely have to<\/a><\/h3>\n<p>The following code snippet from the C++ core guidelines has a bug.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">extern<\/span> atomic<span style=\"color: #555555;\">&lt;<\/span>Link<span style=\"color: #555555;\">*&gt;<\/span> head;        <span style=\"color: #0099ff; font-style: italic;\">\/\/ the shared head of a linked list<\/span>\r\n\r\nLink<span style=\"color: #555555;\">*<\/span> nh <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> Link(data, nullptr);    <span style=\"color: #0099ff; font-style: italic;\">\/\/ make a link ready for insertion<\/span>\r\nLink<span style=\"color: #555555;\">*<\/span> h <span style=\"color: #555555;\">=<\/span> head.load();                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ read the shared head of the list<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">do<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (h<span style=\"color: #555555;\">-&gt;<\/span>data <span style=\"color: #555555;\">&lt;=<\/span> data) <span style=\"color: #006699; font-weight: bold;\">break<\/span>;        <span style=\"color: #0099ff; font-style: italic;\">\/\/ if so, insert elsewhere<\/span>\r\n    nh<span style=\"color: #555555;\">-&gt;<\/span>next <span style=\"color: #555555;\">=<\/span> h;                      <span style=\"color: #0099ff; font-style: italic;\">\/\/ next element is the previous head<\/span>\r\n} <span style=\"color: #006699; font-weight: bold;\">while<\/span> (<span style=\"color: #555555;\">!<\/span>head.compare_exchange_weak(h, nh));    <span style=\"color: #0099ff; font-style: italic;\">\/\/ write nh to head or to h<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Find the bug and write me an e-mail. I will mention the best problem analysis in my next post if you like your name.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Of course, I will solve the riddle of the ABA problem in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-the-rules-to-lock-free-programming\">next post<\/a>. Afterward, my story with lock-free programming continues.&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, I will finish the rules for concurrency and continue directly with lock-free programming. Yes, you have read it correctly: lock-free programming.<\/p>\n","protected":false},"author":21,"featured_media":5456,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[483],"class_list":["post-5459","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-lock-free"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5459","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=5459"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5459\/revisions"}],"predecessor-version":[{"id":6822,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5459\/revisions\/6822"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5456"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5459"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5459"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5459"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}