title: Why is notify required inside a critical section?
body: <p>I'm reading this book <a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-api.pdf" rel="nofollow noreferrer">here</a> (official link, it's free) to understand threads and parallel programming.</p>
  
  <p>Here's the question.</p>
  
  <ol>
  <li>Why does the book say that <code>pthread_cond_signal</code> must be done with a lock held to prevent data race? I wasn't sure, so I referred to <a href="https://stackoverflow.com/questions/17101922/do-i-have-to-acquire-lock-before-calling-condition-variable-notify-one">this question</a> (and <a href="https://stackoverflow.com/questions/20982270/sync-is-unreliable-using-stdatomic-and-stdcondition-variable">this question</a> too), which basically said "no, it's not required". Why would a race condition occur?</li>
  <li>What and where is the race condition being described?</li>
  </ol>
  
  <p>The code and passage in question is as follows. </p>
  
  <blockquote>
  ...  <br>
  The code to wake a thread, which would run in some other thread, looks like this:
  
  <pre><code>pthread_mutex_lock(&amp;lock);
  ready = 1;
  pthread_cond_signal(&amp;cond);
  pthread_mutex_unlock(&amp;lock);
  </code></pre>
  
  
  A few things to note about this code sequence. First, when signaling (as well as when modifying the global variable ready), we always make sure to have the lock held. This ensures that we don’t accidentally introduce a race condition into our code.
  ...
  </blockquote>
  
  <p><sub>(please refer to the free, official pdf to get context.)</sub></p>
  
  <p>I couldn't comment with a small question in the link-2, so here is a full question. </p>
  
  <p><strong>Edit 1:</strong> I understand the lock is to control access to the <code>ready</code> variable. I am wondering why there's a race condition associated with the signaling. Specifically, </p>
  
  <blockquote>
  First, when signaling [...] we always make sure to have the lock held. This ensures that we don’t accidentally introduce a race condition into our code 
  </blockquote>
  
  <p><strong>Edit 2:</strong> I've seen resources and comments (from links commented below and during my own research), sometimes within the same page that say <i>it doesn't matter</i> or <i>you must put it within a lock for Predictable Behavior<sup>TM</sup></i> (would be nice if this can be touched upon too, if the behavior can be other than spurious wakeups). What must I follow? </p>
  
  <p><strong>Edit 3:</strong> I'm looking for more of a 'theoretical' answer, not implementation specific so that I can understand the core idea. I understand answers to these can be platform specific, but an answer that focuses on the core ideas of <code>lock</code>, <code>mutex</code>, <code>condition variable</code> as all implementations must follow these semantics, perhaps adding their own little quirks. Example, <code>wait()</code> can wake up spuriously, and given bad timing of signaling, can happen on 'pure' implementations too. Mentioning these would help.</p>
  
  <p>My apologies for so many edits, but my dearth of in-depth knowledge in this field is confusing the heck outta me. </p>
  
  <p>Any insight would be really helpful, thanks. Also, please feel free to point me to books where I can read these concepts in <em>detail</em>, and where I can learn C++ with these concepts too. Thanks.</p>