{"id":5258,"date":"2017-05-14T20:27:09","date_gmt":"2017-05-14T20:27:09","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/race-condition-versus-data-race\/"},"modified":"2023-06-26T12:16:24","modified_gmt":"2023-06-26T12:16:24","slug":"race-condition-versus-data-race","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/race-condition-versus-data-race\/","title":{"rendered":"Race Conditions versus Data Races"},"content":{"rendered":"<p>Race conditions and data races are related but different concepts. Because they are related, they are often confused. In German, we even translate both expressions with the term <em>kritischer Wettlauf<\/em>. That is very bad. To reason about concurrency, your wording must be exact. Therefore, this post is about race conditions and data races.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p>At a starting point, let me define both terms in the software domain.<\/p>\n<ul>\n<li><strong>Race condition: <\/strong>A race condition is a situation in which the result of an operation depends on the interleaving of certain individual operations.<\/li>\n<li><strong>Data race<\/strong>: A data race is when at least two threads access a shared variable simultaneously. At least one thread tries to modify the variable.<\/li>\n<\/ul>\n<p>A race condition is, per see, not bad. A race condition can be the reason for a data race. On the contrary, a data race is an undefined behavior. Therefore, all reasoning about your program makes no sense anymore.<\/p>\n<p>Before I present you with different kinds of race conditions that are not benign, I want to show you a program with a race condition and a data race.<\/p>\n<h2>A race condition and a data race<\/h2>\n<p>The classic example of a race condition and a data race is a function that transfers money from one account to another. In the single-threaded case, all is fine.<\/p>\n<h3>Single-threaded<\/h3>\n<p>&nbsp;<\/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: #0099ff; font-style: italic;\">\/\/ account.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Account{                                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ 1<\/span>\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> balance{<span style=\"color: #ff6600;\">100<\/span>};\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">transferMoney<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> amount, Account<span style=\"color: #555555;\">&amp;<\/span> from, Account<span style=\"color: #555555;\">&amp;<\/span> to){\r\n  <span style=\"color: #006699; font-weight: bold;\">if<\/span> (from.balance <span style=\"color: #555555;\">&gt;=<\/span> amount){                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ 2<\/span>\r\n    from.balance -<span style=\"color: #555555;\">=<\/span> amount;                    \r\n    to.balance +<span style=\"color: #555555;\">=<\/span> amount;\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  \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  Account account1;\r\n  Account account2;\r\n\r\n  transferMoney(<span style=\"color: #ff6600;\">50<\/span>, account1, account2);         <span style=\"color: #0099ff; font-style: italic;\">\/\/ 3<\/span>\r\n  transferMoney(<span style=\"color: #ff6600;\">130<\/span>, account2, account1);\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"account1.balance: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> account1.balance <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"account2.balance: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> account2.balance <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\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}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The workflow is quite simple to make my point clear. Each account starts with a balance of 100 $ (1). To withdraw money, there must be enough money in the account (2). If enough money is available, the amount will be first removed from the old account and then added to the new one. Two money transfers take place (3). One from <span style=\"font-family: courier new,courier;\">account1<\/span> to <span style=\"font-family: courier new,courier;\">account2<\/span>, and the other way around. Each invocation of <span style=\"font-family: courier new,courier;\">transferMoney<\/span> happens after the other. They are a kind of transaction that establishes a total order. That is fine.<\/p>\n<p>The balance of both accounts looks good.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5256\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/05\/account.png\" alt=\"account\" style=\"margin: 15px;\" width=\"369\" height=\"160\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/05\/account.png 369w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/05\/account-300x130.png 300w\" sizes=\"auto, (max-width: 369px) 100vw, 369px\" \/><\/p>\n<p>&nbsp;In real life, <span style=\"font-family: courier new,courier;\">transferMoney<\/span> will be executed concurrently.<\/p>\n<\/p>\n<h3>Multithreading<\/h3>\n<p>&nbsp;No, we have a data race and a race condition.<\/p>\n<p>&nbsp;<\/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: #0099ff; font-style: italic;\">\/\/ accountThread.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;functional&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;thread&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Account{\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> balance{<span style=\"color: #ff6600;\">100<\/span>};\r\n};\r\n                                                      <span style=\"color: #0099ff; font-style: italic;\">\/\/ 2<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">transferMoney<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> amount, Account<span style=\"color: #555555;\">&amp;<\/span> from, Account<span style=\"color: #555555;\">&amp;<\/span> to){\r\n  <span style=\"color: #006699; font-weight: bold;\">using<\/span> <span style=\"color: #006699; font-weight: bold;\">namespace<\/span> std<span style=\"color: #555555;\">::<\/span>chrono_literals;\r\n  <span style=\"color: #006699; font-weight: bold;\">if<\/span> (from.balance <span style=\"color: #555555;\">&gt;=<\/span> amount){\r\n    from.balance <span style=\"color: #555555;\">-=<\/span> amount;  \r\n    std<span style=\"color: #555555;\">::<\/span>this_thread<span style=\"color: #555555;\">::<\/span>sleep_for(<span style=\"color: #ff6600;\">1<\/span>ns);                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ 3<\/span>\r\n    to.balance <span style=\"color: #555555;\">+=<\/span> amount;\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  \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  Account account1;\r\n  Account account2;\r\n                                                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ 1<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> thr1(transferMoney, <span style=\"color: #ff6600;\">50<\/span>, std<span style=\"color: #555555;\">::<\/span>ref(account1), std<span style=\"color: #555555;\">::<\/span>ref(account2));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> thr2(transferMoney, <span style=\"color: #ff6600;\">130<\/span>, std<span style=\"color: #555555;\">::<\/span>ref(account2), std<span style=\"color: #555555;\">::<\/span>ref(account1));\r\n  \r\n  thr1.join();\r\n  thr2.join();\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"account1.balance: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> account1.balance <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"account2.balance: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> account2.balance <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\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}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The calls of<span style=\"font-family: courier new,courier;\"> transferMoney<\/span> will be executed concurrently (1). The arguments to a function, executed by a thread, must be moved or copied by value. If a reference such as <span style=\"font-family: courier new,courier;\"> account1<\/span> or <span style=\"font-family: courier new,courier;\">account2<\/span> needs to be passed to the thread function, you must wrap it in a reference wrapper like <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/utility\/functional\/ref\">std::ref<\/a>. Because of the threads <span style=\"font-family: courier new,courier;\">t1<\/span> and<span style=\"font-family: courier new,courier;\"> t2,<\/span> there is a data race on the account&#8217;s balance in the function <span style=\"font-family: courier new,courier;\">transferMoney<\/span> (2). But where is the race condition? To make the race condition visible, I put the threads&nbsp;for a short period to sleep (3). The built-in literal <span style=\"font-family: courier new,courier;\">1ns<\/span> in the expression <span style=\"font-family: courier new,courier;\">std<span style=\"color: #555555;\">::<\/span>this_thread<span style=\"color: #555555;\">::<\/span>sleep_for(<span style=\"color: #000000;\">1<\/span>ns)<\/span> stands for a nanosecond. In the post,&nbsp;<a href=\"https:\/\/www.modernescpp.com\/index.php\/raw-and-cooked\">Raw and Cooked<\/a> are the details of the new built-in literals. We have had them for time durations since C++14.<\/p>\n<p>By the way. A short sleep period in concurrent programs is often sufficient to make an issue visible.<\/p>\n<p>Here is the output of the program.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5257\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/05\/accountThreads.png\" alt=\"accountThreads\" style=\"margin: 15px;\" width=\"369\" height=\"160\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/05\/accountThreads.png 369w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/05\/accountThreads-300x130.png 300w\" sizes=\"auto, (max-width: 369px) 100vw, 369px\" \/><\/p>\n<p>And you see. Only the first function <span style=\"font-family: courier new,courier;\">transferMoney <\/span>was executed. The second one was not performed because the balance was too small. The reason is that the second withdrawal happened before the first money transfer was completed. Here we have our race condition.<\/p>\n<p>Solving the data race is relatively easy. The operations on balance have to be protected. I did it with an atomic variable.<\/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: #0099ff; font-style: italic;\">\/\/ accountThreadAtomic.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;atomic&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;functional&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;thread&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Account{\r\n  std<span style=\"color: #555555;\">::<\/span>atomic<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> balance{<span style=\"color: #ff6600;\">100<\/span>};\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">transferMoney<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> amount, Account<span style=\"color: #555555;\">&amp;<\/span> from, Account<span style=\"color: #555555;\">&amp;<\/span> to){\r\n  <span style=\"color: #006699; font-weight: bold;\">using<\/span> <span style=\"color: #006699; font-weight: bold;\">namespace<\/span> std<span style=\"color: #555555;\">::<\/span>chrono_literals;\r\n  <span style=\"color: #006699; font-weight: bold;\">if<\/span> (from.balance <span style=\"color: #555555;\">&gt;=<\/span> amount){\r\n    from.balance <span style=\"color: #555555;\">-=<\/span> amount;  \r\n    std<span style=\"color: #555555;\">::<\/span>this_thread<span style=\"color: #555555;\">::<\/span>sleep_for(<span style=\"color: #ff6600;\">1<\/span>ns);\r\n    to.balance <span style=\"color: #555555;\">+=<\/span> amount;\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  \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  Account account1;\r\n  Account account2;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> thr1(transferMoney, <span style=\"color: #ff6600;\">50<\/span>, std<span style=\"color: #555555;\">::<\/span>ref(account1), std<span style=\"color: #555555;\">::<\/span>ref(account2));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> thr2(transferMoney, <span style=\"color: #ff6600;\">130<\/span>, std<span style=\"color: #555555;\">::<\/span>ref(account2), std<span style=\"color: #555555;\">::<\/span>ref(account1));\r\n  \r\n  thr1.join();\r\n  thr2.join();\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"account1.balance: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> account1.balance <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"account2.balance: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> account2.balance <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\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}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Of course, the atomic variable will not solve the race condition. Only the data race is gone.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>I only presented an erroneous program having a data race and a race condition. But there are many different aspects of malicious race conditions. Breaking of invariants, locking issues such as deadlock or livelocks, or lifetime issues of detached threads. We also have deadlocks without race conditions. In the <a href=\"https:\/\/www.modernescpp.com\/index.php\/malicious-race-conditions\">next post<\/a>, I write about the malicious effects of race conditions.<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Race conditions and data races are related but different concepts. Because they are related, they are often confused. In German, we even translate both expressions with the term kritischer Wettlauf. That is very bad. To reason about concurrency, your wording must be exact. Therefore, this post is about race conditions and data races.<\/p>\n","protected":false},"author":21,"featured_media":5256,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[366],"tags":[506],"class_list":["post-5258","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-multithreading","tag-race-conditions"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5258","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=5258"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5258\/revisions"}],"predecessor-version":[{"id":6872,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5258\/revisions\/6872"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5256"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5258"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5258"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5258"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}