{"id":4744,"date":"2016-05-10T20:13:00","date_gmt":"2016-05-10T20:13:00","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/the-risk-of-mutexes\/"},"modified":"2023-06-26T12:58:29","modified_gmt":"2023-06-26T12:58:29","slug":"the-risk-of-mutexes","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/the-risk-of-mutexes\/","title":{"rendered":"The Risks of Mutexes"},"content":{"rendered":"<p>The usage of mutexes seems extremely simple. There is a critical section in the code that a single thread can only access at any point in time. It&#8217;s ensured by a mutex <span style=\"font-family: courier new,courier;\">m<\/span>. The calls <span style=\"font-family: courier new,courier;\">m.lock()<\/span> and <span style=\"font-family: courier new,courier;\">m.unlock()<\/span> guarantee this exclusivity. But the devil is in the details.<\/p>\n<p><!--more--><\/p>\n<h2>Deadlock<\/h2>\n<p>The different names for deadlocks are frightening. Some call them deadly embrace &nbsp;(hug of death :-)? or kiss of death. But wait, what is a deadlock?<\/p>\n<dl>\n<dt>Deadlock<\/dt>\n<dd>&nbsp;&nbsp;&nbsp;A deadlock is a state in which at least two threads are blocked because each thread is waiting for the release of some resource with which the other thread works before it releases its resource.<\/dd>\n<dd><\/dd>\n<dd><\/dd>\n<dd><\/dd>\n<dd><\/dd>\n<dd>\n<p>The result of a deadlock is a total standstill. The Thread and usually the whole program is <strong>blocked forever<\/strong>. It is easy to produce a deadlock. Curious?<\/p>\n<h3>Exceptions and unknown code<\/h3>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">std::mutex m;\r\nm.lock();\r\nsharedVariable= getVar();\r\nm.unlock();\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>If the unknown code in the function<span style=\"font-family: courier new,courier;\"> getVar()<\/span> throws an exception,&nbsp;<span style=\"font-family: courier new,courier;\">m.unlock()<\/span> will not be called. Every attempt to ask for the mutex <span style=\"font-family: courier new,courier;\">m<\/span>&nbsp;will fail, and&nbsp;the program will block. Forever. But that is not the only issue with that piece of code. It calls some (unknown to us) function<span style=\"font-family: courier new,courier;\">&nbsp;get.Var()<\/span>, while <span style=\"font-family: courier new,courier;\">m.lock()<\/span> is active. What will happen if the function <span style=\"font-family: courier new,courier;\">getVar()<\/span> tries to get the same lock? Of course, you know it\u2014a deadlock.<\/p>\n<p>Do you want to have a more visual example?<\/p>\n<\/p>\n<h3>Lock mutexes in a different order<\/h3>\n<\/dd>\n<dd><\/dd>\n<dd><\/dd>\n<\/dl>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4742\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/Deadlock.png\" alt=\"Deadlock\" width=\"600\" height=\"417\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/Deadlock.png 803w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/Deadlock-300x208.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/Deadlock-768x534.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Thread 1 and 2 need access to two resources to finish their work. Unfortunately, they ask for the resources protected by two mutexes in a different order. In this case, the thread executions will interleave so that thread 1 gets mutex 1, then thread 2 gets mutex 2, and we have a standstill. Each thread wants to get the other&#8217;s mutex. For this, the thread has to wait for the release of the resource.<\/p>\n<p>&nbsp;<\/p>\n<p>It&#8217;s easy to express the picture in code.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; 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<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ deadlock.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;chrono&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;mutex&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;thread&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">struct<\/span> CriticalData{\r\n  std::mutex mut;\r\n};\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> deadLock(CriticalData&amp; a, CriticalData&amp; b){\r\n\r\n  a.mut.lock();\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"get the first mutex\"<\/span> &lt;&lt; std::endl;\r\n  std::this_thread::sleep_for(std::chrono::milliseconds(1));\r\n  b.mut.lock();\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"get the second mutex\"<\/span> &lt;&lt; std::endl;\r\n  <span style=\"color: #008000;\">\/\/ do something with a and b<\/span>\r\n  a.mut.unlock();\r\n  b.mut.unlock();\r\n  \r\n}\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  CriticalData c1;\r\n  CriticalData c2;\r\n\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> t1([&amp;]{deadLock(c1,c2);});\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> t2([&amp;]{deadLock(c2,c1);});\r\n\r\n  t1.join();\r\n  t2.join();\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Thread<span style=\"font-family: courier new,courier;\"> t1<\/span> and thread <span style=\"font-family: courier new,courier;\">t2<\/span> call the function <span style=\"font-family: courier new,courier;\">deadlock<\/span> (lines 12 &#8211; 20). To process <span style=\"font-family: courier new,courier;\">deadlock<\/span>, both functions need the &nbsp;<span style=\"font-family: 'courier new', courier;\">CriticalData<\/span><span style=\"font-family: courier new,courier;\"> c1<\/span> and <span style=\"font-family: courier new,courier;\">c2<\/span> (lines 27 and 28). Because the objects<span style=\"font-family: courier new,courier;\"> c1<\/span> and <span style=\"font-family: courier new,courier;\">c2<\/span> must be protected from shared access, they &nbsp;have a mutex (to keep this example code short and straightforward <span style=\"font-family: 'courier new', courier;\">CriticalData&nbsp;<\/span>doesn&#8217;t have any other methods or members apart from mutex)<\/p>\n<p>Only a sleep about 1 Millisecond in line 16, and we have the deadlock.<span style=\"font-family: arial,helvetica,sans-serif;\"><\/span><br \/>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4743\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/deadlockCode.png\" alt=\"deadlockCode\" width=\"517\" height=\"217\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/deadlockCode.png 517w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/05\/deadlockCode-300x126.png 300w\" sizes=\"auto, (max-width: 517px) 100vw, 517px\" \/><\/p>\n<p>The only choice now is the press CTRL+C to kill the process.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Honestly, the example will not boost your confidence in writing multithreading programs. Additionally, the complexity will increase to the power of 2, which each new mutex. The solution to the problem is locks because they safely encapsulate mutexes. How? Have a look<a href=\"https:\/\/www.modernescpp.com\/index.php\/prefer-locks-to-mutexes\"> here<\/a>. (<strong>Proofreader Alexey<\/strong> <strong>Elymanov<\/strong>)<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The usage of mutexes seems extremely simple. There is a critical section in the code that a single thread can only access at any point in time. It&#8217;s ensured by a mutex m. The calls m.lock() and m.unlock() guarantee this exclusivity. But the devil is in the details.<\/p>\n","protected":false},"author":21,"featured_media":4742,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[366],"tags":[433],"class_list":["post-4744","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-multithreading","tag-mutex"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4744","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=4744"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4744\/revisions"}],"predecessor-version":[{"id":6984,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4744\/revisions\/6984"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/4742"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=4744"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=4744"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=4744"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}