Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You should check for new data as soon as <code>pthread_cond_wait</code> returns, and wait again if there's no new data. That can happen if you get a spurious wake (think of it as the kernel accidentally waking you up by dropping something heavy down the stairs), and it would be better to wait immediately instead of changing <code>workerWaiting</code> then unlocking and relocking the mutex twice before waiting again.</p> <p>An RAII lock type would make the code so much cleaner:</p> <pre><code> while(true) { while(true) { { scoped_lock l(&amp;manager-&gt;mutex); if(/* new data available */) { /* copy new data from shared to thread memory */ } else break; } /* process the data in thread memory */ scoped_lock l(&amp;manager-&gt;mutex); /* copy results back to shared memory */ } scoped_lock l(&amp;manager-&gt;mutex); // check if we should continue running if(!manager-&gt;workerRunning) break; // wait for new data to arrive manager-&gt;workerWaiting = true; while (!/* new data available */) pthread_cond_wait(&amp;manager-&gt;condition, &amp;manager-&gt;mutex); manager-&gt;workerWaiting = false; } </code></pre> <p>Using <code>pthread_cancel</code> as Oleg suggests would simplify it even further.</p> <p>Following your edit to the code to handle spurious wake-ups, it becomes much simpler if you use RAII and restructure it:</p> <pre><code> while(true) { { scoped_lock l(&amp;manager-&gt;mutex); // wait for new data to arrive while(manager-&gt;workerRunning &amp;&amp; !/* new data available*/) pthread_cond_wait(&amp;manager-&gt;condition, &amp;manager-&gt;mutex); // check if we should continue running if(!manager-&gt;workerRunning) break; /* copy new data from shared to thread memory */ } /* process the data in thread memory */ scoped_lock l(&amp;manager-&gt;mutex); /* copy results back to shared memory */ } return NULL; </code></pre> <p>Without something like scoped_lock, what happens if <code>/* copy new data from shared to thread memory */</code> or <code>/* process the data in thread memory */</code> throws an exception? You'll never unlock the mutex.</p> <p>The RAII type could be as simple as:</p> <pre><code>struct scoped_lock { explicit scoped_lock(pthrad_mutex_t* m) : mx(m) { pthread_mutex_lock(mx); } ~scoped_lock() { pthread_mutex_unlock(mx); } private: pthread_mutex_t* mx; scoped_lock(const scoped_lock&amp;); scoped_lock operator=(const scoped_lock&amp;); }; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload