{"id":4797,"date":"2016-06-21T06:16:17","date_gmt":"2016-06-21T06:16:17","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/the-atomic-boolean\/"},"modified":"2016-06-21T06:16:17","modified_gmt":"2016-06-21T06:16:17","slug":"the-atomic-boolean","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/the-atomic-boolean\/","title":{"rendered":"The Atomic Boolean"},"content":{"rendered":"<p>The remaining atomics &#8211; in contrast to std::atomic_flag &#8211; are partial or full specializations of the class template <span style=\"font-family: courier new,courier;\">std::atomic<\/span>. Let&#8217;s start with <span style=\"font-family: courier new,courier;\">std::atomic&lt;bool&gt;.<\/span><\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<h2>std::atomic&lt;bool&gt;<\/h2>\n<p><span style=\"font-family: courier new,courier;\">std::atomic&lt;bool&gt;<\/span> has a lot more to offer than <span style=\"font-family: courier new,courier;\">std::atomic_flag<\/span>. It can explicitly be set to <span style=\"font-family: courier new,courier;\">true<\/span> or <span style=\"font-family: courier new,courier;\">false.<\/span> That&#8217;s enough to synchronize two threads. So I can simulate <a href=\"https:\/\/www.modernescpp.com\/index.php\/condition-variables\">condition variables<\/a> with atomic variables.<\/p>\n<p>Let&#8217;s first have a look at condition variables.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n49<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ conditionVariable.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;condition_variable&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;thread&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;vector&gt;<\/span>\r\n\r\nstd::vector&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; mySharedWork;\r\nstd::mutex mutex_;\r\nstd::condition_variable condVar;\r\n\r\n<span style=\"color: #2b91af;\">bool<\/span> dataReady;\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> waitingForWork(){\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"Waiting \"<\/span> &lt;&lt; std::endl;\r\n    std::unique_lock&lt;std::mutex&gt; lck(mutex_);\r\n    condVar.wait(lck,[]{<span style=\"color: #0000ff;\">return<\/span> dataReady;});\r\n    mySharedWork[1]= 2;\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"Work done \"<\/span> &lt;&lt; std::endl;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> setDataReady(){\r\n    mySharedWork={1,0,3};\r\n    {\r\n        std::lock_guard&lt;std::mutex&gt; lck(mutex_);\r\n        dataReady=true;\r\n    }\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"Data prepared\"<\/span> &lt;&lt; std::endl;\r\n    condVar.notify_one();\r\n}\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n    \r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> t1(waitingForWork);\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> t2(setDataReady);\r\n\r\n  t1.join();\r\n  t2.join();\r\n  \r\n   <span style=\"color: #0000ff;\">for<\/span> (<span style=\"color: #0000ff;\">auto<\/span> v: mySharedWork){\r\n      std::cout &lt;&lt; v &lt;&lt; <span style=\"color: #a31515;\">\" \"<\/span>;\r\n  }\r\n      \r\n  \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"\\n\\n\"<\/span>;\r\n  \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>And now the pendant with atomic booleans.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ atomicCondition.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;atomic&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;chrono&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;thread&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;vector&gt;<\/span>\r\n\r\nstd::vector&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; mySharedWork;\r\nstd::atomic&lt;<span style=\"color: #2b91af;\">bool<\/span>&gt; dataReady(false);\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> waitingForWork(){\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"Waiting \"<\/span> &lt;&lt; std::endl;\r\n    <span style=\"color: #0000ff;\">while<\/span> ( !dataReady.load() ){             <strong><span style=\"color: #ff0000;\">\/\/ (3)<\/span><\/strong>\r\n        std::this_thread::sleep_for(std::chrono::milliseconds(5));\r\n    }\r\n    mySharedWork[1]= 2;                      <strong><span style=\"color: #ff0000;\">\/\/ (4)<\/span><\/strong>\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"Work done \"<\/span> &lt;&lt; std::endl;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> setDataReady(){\r\n    mySharedWork={1,0,3};                    <strong><span style=\"color: #ff0000;\">\/\/ (1)<\/span><\/strong>\r\n    dataReady= true;                       <strong><span style=\"color: #ff0000;\">  \/\/ (2)<\/span><\/strong>\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"Data prepared\"<\/span> &lt;&lt; std::endl;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n    \r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> t1(waitingForWork);\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> t2(setDataReady);\r\n\r\n  t1.join();\r\n  t2.join();\r\n  \r\n  <span style=\"color: #0000ff;\">for<\/span> (<span style=\"color: #0000ff;\">auto<\/span> v: mySharedWork){\r\n      std::cout &lt;&lt; v &lt;&lt; <span style=\"color: #a31515;\">\" \"<\/span>;\r\n  }\r\n      \r\n  \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"\\n\\n\"<\/span>;\r\n  \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>What guarantees that line 17 will be executed after line 14? Or, to say it more generally, the thread t1 will execute <span style=\"font-family: courier new,courier;\">mySharedWork[1]= 2<\/span> (line 17) after thread t2 had executed <span style=\"font-family: courier new,courier;\">mySharedWork={1,0,3}<\/span> (line 22). Now it gets more formal.<\/p>\n<ul>\n<li>Line22<span style=\"color: #ff0000;\"> <strong>(1)<\/strong><\/span> <em>happens-before<\/em> line 23 <strong><span style=\"color: #ff0000;\">(2)<\/span><\/strong><\/li>\n<li>Line 14 <strong><span style=\"color: #ff0000;\">(3)<\/span> <\/strong><em>happens-before<\/em> line 17 <strong><span style=\"color: #ff0000;\">(4)<\/span><\/strong><\/li>\n<li>Line 23 <strong><span style=\"color: #ff0000;\">(2)<\/span><\/strong> <em>synchronizes-with<\/em> line 14 <span style=\"color: #ff0000;\"><strong>(3)<\/strong><\/span><\/li>\n<li>Because <em>happens-before <\/em>is transitive, it follows: <span style=\"font-family: courier new,courier;\">mySharedWork={1,0,3}<\/span> <strong><span style=\"color: #ff0000;\">(1)<\/span><\/strong><em> happens-before<\/em> <span style=\"font-family: courier new,courier;\">mySharedWork[1]= 2 <strong><span style=\"color: #ff0000;\">(4)<\/span><\/strong> <\/span><\/li>\n<\/ul>\n<p>I want to mention one point explicitly. Because of the condition variable <span style=\"font-family: courier new,courier;\">condVar<\/span> or the atomic <span style=\"font-family: courier new,courier;\">dataReady,<\/span> the access to the shared variable <span style=\"font-family: courier new,courier;\">mySharedWork<\/span> is synchronized. This holds, although <span style=\"font-family: courier new,courier;\">mySharedWork<\/span> is not protected by a lock or itself an atomic.<\/p>\n<p><span style=\"color: #ff0000;\"><span style=\"color: #000000;\">Both programs produce the same result for <span>mySharedWork.<\/span><\/span><\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4796\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/06\/conditionVariableAtomic.png\" alt=\"conditionVariableAtomic\" width=\"466\" height=\"335\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/06\/conditionVariableAtomic.png 466w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/06\/conditionVariableAtomic-300x216.png 300w\" sizes=\"auto, (max-width: 466px) 100vw, 466px\" \/><\/p>\n<h3>Push versus pull principle<\/h3>\n<p>I cheated a little. One difference exists between the synchronization of the threads with the condition variable and the atomic boolean. The condition variable notifies the waiting thread <span style=\"font-family: courier new,courier;\">(condVar.notify())<\/span> that it should proceed with its work. But the waiting thread with the atomic boolean checks if the sender is done with its work (<span style=\"font-family: courier new,courier;\">dataRead= true<\/span>).<\/p>\n<p>The condition variable notifies the waiting thread (push principle). The atomic boolean repeatedly asks for the value (pull principle).<\/p>\n<\/p>\n<h2>compare_exchange_strong and compare_exchange_weak<\/h2>\n<p><span style=\"font-family: courier new,courier;\">std::atomic&lt;bool&gt;<\/span> and the&nbsp;full or partial specializations of <span style=\"font-family: courier new,courier;\">std::atomic<\/span> supports the bread and butter of all atomic operations: <span style=\"font-family: courier new,courier;\">compare_exchange_strong<\/span>. This function has the syntax: <span style=\"font-family: courier new,courier;\">bool compare_exchange_strong(T&amp; expected, T&amp; desired<\/span>). Because this operation compares and exchanges in one atomic operation, a value is often called compare_and_swap (CAS). This kind of operation is in a lot of programming languages available. Of course, the behavior may differ a little.<\/p>\n<p>A call of <span style=\"font-family: courier new,courier;\">atomicValue.compare_exchange_strong(expected, desired)<\/span> obeys the following strategy. If the atomic comparison of <span style=\"font-family: courier new,courier;\">atomicValue<\/span> with expected returns <span style=\"font-family: courier new,courier;\">true,<\/span> the value of <span style=\"font-family: courier new,courier;\">atomicValue<\/span> is set in the same atomic operation as desired. If the comparison returns <span style=\"font-family: courier new,courier;\">false,<\/span> <span style=\"font-family: courier new,courier;\">expected<\/span> will be set to <span style=\"font-family: courier new,courier;\">atomicValue.<\/span> The reason why the operation <span style=\"font-family: courier new,courier;\">compare_exchange_strong<\/span> is called strong is simple. There is a method <span style=\"font-family: courier new,courier;\">compare_exchange_weak<\/span>. This weak version can spuriously fail. That means, although<span style=\"font-family: courier new,courier;\"> *atomicValue == expected<\/span> holds, the weak variant returns <span style=\"font-family: courier new,courier;\">false.<\/span> So you must check the condition in a loop: <span style=\"font-family: courier new,courier;\">while ( !atomicValue.compare_exchange_weak(expected, desired) ).<\/span> The reason for the weak form is performance. On some platforms, the weak is faster than the strong variant.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>The <a href=\"https:\/\/www.modernescpp.com\/index.php\/atomics\">next post<\/a> will be about the class template <span style=\"font-family: courier new,courier;\">std::atomic<\/span>. So I write about the different specializations for integrals and pointers. They provide a richer interface than the atomic boolean <span style=\"font-family: courier new,courier;\">std::atomic&lt;bool&gt;.<\/span> (<strong>Proofreader Alexey Elymanov<\/strong>)&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The remaining atomics &#8211; in contrast to std::atomic_flag &#8211; are partial or full specializations of the class template std::atomic. Let&#8217;s start with std::atomic&lt;bool&gt;.<\/p>\n","protected":false},"author":21,"featured_media":4796,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[368],"tags":[],"class_list":["post-4797","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-multithreading-memory-model"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4797","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=4797"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4797\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/4796"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=4797"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=4797"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=4797"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}