Note that there are some explanatory texts on larger screens.

plurals
  1. POPThread beginner - starting, syncing, stopping a worker thread
    text
    copied!<p>I have the following manager&lt;->worker situation:</p> <pre><code>class Manager { private: pthread_attr_t workerSettings; pthread_t worker; pthread_cond_t condition; pthread_mutex_t mutex; bool workerRunning; static void* worker_function(void* args) { Manager* manager = (Manager*)args; while(true) { while(true) { pthread_mutex_lock(&amp;manager-&gt;mutex); if(/* new data available */) { /* copy new data from shared to thread memory */ pthread_mutex_unlock(&amp;manager-&gt;mutex); } else { pthread_mutex_unlock(&amp;manager-&gt;mutex); break; } /* process the data in thread memory */ pthread_mutex_lock(&amp;manager-&gt;mutex); /* copy results back to shared memory */ pthread_mutex_unlock(&amp;manager-&gt;mutex); } pthread_mutex_lock(&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) { pthread_mutex_unlock(&amp;manager-&gt;mutex); break; } pthread_mutex_unlock(&amp;manager-&gt;mutex); } pthread_exit(NULL); return NULL; // just to avoid the missing return statement compiler warning } public: Manager() : workerRunning(true) { pthread_cond_init(&amp;condition, NULL); pthread_mutex_init(&amp;mutex, NULL); pthread_attr_init(&amp;workerSettings); pthread_attr_setdetachstate(&amp;workerSettings, PTHREAD_CREATE_JOINABLE); pthread_create(&amp;worker, &amp;workerSettings, worker_function, (void*)this); } // this *may* be called repeatedly or very seldom void addData(void) { pthread_mutex_lock(&amp;mutex); /* copy new data into shared memory */ pthread_cond_signal(&amp;condition); pthread_mutex_unlock(&amp;mutex); } ~Manager() { // set workerRunning to false and signal the worker pthread_mutex_lock(&amp;mutex); workerRunning = false; pthread_cond_signal(&amp;condition); pthread_mutex_unlock(&amp;mutex); // wait for the worker to exit pthread_join(worker, NULL); // cleanup pthread_attr_destroy(&amp;workerSettings); pthread_mutex_destroy(&amp;mutex); pthread_cond_destroy(&amp;condition); } }; </code></pre> <p>I'm not completely sure about this at several places:</p> <ul> <li>Is the fact that Manager spawns a new thread in its constructor considered a bad practice? (I will only have one Manager object, so i guess that should be fine)</li> <li>What about the pthread_exit - i see this in many tutorials but i don't quite get why it should be there? Can't i simply return the function to exit the thread? I also think the return NULL is dead code, but gcc warns when it's missing because it obviously can't know that pthread_exit already killed the thread at that point.</li> <li>About the constructor - can i destroy the thread attr object (workerSettings) immediately after spawning the thread or does it have to stay valid for the entire lifetime of the thread?</li> <li>About the destructor: Is this the right way to do this?</li> </ul> <p>And most importantly:</p> <ul> <li>Do your experienced eyes see any synchronization issues there?</li> </ul> <p>Thanks for your help!</p>
 

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