title: Why can mutex be used in different threads?
body: <ol>
  <li><p>Using (writing) same variable in multiple threads simultaneously causes undefined behavior and crashes.
  Why using mutex, despite on fact that they are also variables, not causes undefined behavior?</p>
  </li>
  <li><p>If mutex somehow can be used simultaneously, why not make all variables work simultaneously without locking?</p>
  </li>
  </ol>
  <p>All my research is pressing <code>Show definition</code> on <code>mutex::lock</code> in Visual Studio, where I get at the end <code>_Mtx_lock</code> function without realization, and then I found it’s <a href="https://docs.microsoft.com/en-us/answers/questions/190833/how-to-debug-int-mtx-lock-mtx-t-mtx-inside-mutexc.html" rel="nofollow noreferrer">realization (Windows)</a>, though it has some functions also without realization:</p>
  <pre><code> int _Mtx_lock(_Mtx_t mtx)
   {    /* lock mutex */
   return (mtx_do_lock(mtx, 0));
   }
  
   static int mtx_do_lock(_Mtx_t mtx, const xtime *target)
   {    /* lock mutex */
   if ((mtx-&gt;type &amp; ~_Mtx_recursive) == _Mtx_plain)
       {    /* set the lock */
       if (mtx-&gt;thread_id != static_cast&lt;long&gt;(GetCurrentThreadId()))
           {    /* not current thread, do lock */
           mtx-&gt;_get_cs()-&gt;lock();
           mtx-&gt;thread_id = static_cast&lt;long&gt;(GetCurrentThreadId());
           }
       ++mtx-&gt;count;
  
       return (_Thrd_success);
       }
   else
       {    /* handle timed or recursive mutex */
       int res = WAIT_TIMEOUT;
       if (target == 0)
           {    /* no target --&gt; plain wait (i.e. infinite timeout) */
           if (mtx-&gt;thread_id != static_cast&lt;long&gt;(GetCurrentThreadId()))
               mtx-&gt;_get_cs()-&gt;lock();
           res = WAIT_OBJECT_0;
  
           }
       else if (target-&gt;sec &lt; 0 || target-&gt;sec == 0 &amp;&amp; target-&gt;nsec &lt;= 0)
           {    /* target time &lt;= 0 --&gt; plain trylock or timed wait for */
               /* time that has passed; try to lock with 0 timeout */
               if (mtx-&gt;thread_id != static_cast&lt;long&gt;(GetCurrentThreadId()))
                   {    /* not this thread, lock it */
                   if (mtx-&gt;_get_cs()-&gt;try_lock())
                       res = WAIT_OBJECT_0;
                   else
                       res = WAIT_TIMEOUT;
                   }
               else
                   res = WAIT_OBJECT_0;
  
           }
       else
           {    /* check timeout */
           xtime now;
           xtime_get(&amp;now, TIME_UTC);
           while (now.sec &lt; target-&gt;sec
               || now.sec == target-&gt;sec &amp;&amp; now.nsec &lt; target-&gt;nsec)
               {    /* time has not expired */
               if (mtx-&gt;thread_id == static_cast&lt;long&gt;(GetCurrentThreadId())
                   || mtx-&gt;_get_cs()-&gt;try_lock_for(
                       _Xtime_diff_to_millis2(target, &amp;now)))
                   {    /* stop waiting */
                   res = WAIT_OBJECT_0;
                   break;
                   }
               else
                   res = WAIT_TIMEOUT;
  
               xtime_get(&amp;now, TIME_UTC);
               }
           }
       if (res != WAIT_OBJECT_0 &amp;&amp; res != WAIT_ABANDONED)
           ;
  
       else if (1 &lt; ++mtx-&gt;count)
           {    /* check count */
           if ((mtx-&gt;type &amp; _Mtx_recursive) != _Mtx_recursive)
               {    /* not recursive, fixup count */
               --mtx-&gt;count;
               res = WAIT_TIMEOUT;
               }
           }
       else
           mtx-&gt;thread_id = static_cast&lt;long&gt;(GetCurrentThreadId());
  
       switch (res)
           {
       case WAIT_OBJECT_0:
       case WAIT_ABANDONED:
           return (_Thrd_success);
  
       case WAIT_TIMEOUT:
           if (target == 0 || (target-&gt;sec == 0 &amp;&amp; target-&gt;nsec == 0))
               return (_Thrd_busy);
           else
               return (_Thrd_timedout);
  
       default:
           return (_Thrd_error);
           }
       }
   }
  </code></pre>
  <p>So, according to this code, and the <code>atomic_</code> keywords I think mutex can be written the next way:</p>
  <pre><code>atomic_bool state = false;
  
  void lock()
  {
  if(!state)
      state = true;
  else
      while(state){}
  }
  
  void unlock()
  {
  state = false;
  }
  
  bool try_lock()
  {
  if(!state)
     state = true;
  else
     return false;
  
  return true;
  }
  </code></pre>