title: What are the problems with this producer/consumer implementation?
body: <p>So I'm looking at using a simple producer/consumer queue in C++. I'll end up using boost for threading but this example is just using pthreads. I'll also end up using a far more OO approach, but I think that would obscure the details I'm interested in at the moment.</p>
  
  <p>Anyway the particular issues I'm worried about are</p>
  
  <ol>
  <li>Since this code is using push_back and pop_front of std::deque - it's probably doing allocation and deallocation of the underlying data in different threads - I believe this is bad (undefined behaviour) - what's the easiest way to avoid this?</li>
  <li>Nothing is marked volatile. But the important bits are mutex protected. Do I need to mark anything as volatile and if so what? - I don't think I do as I believe the mutex contains appropriate memory barriers etc., but I'm unsure.</li>
  </ol>
  
  <p>Are there any other glaring issues?</p>
  
  <p>Anyway heres the code:</p>
  
  <pre><code>#include &lt;pthread.h&gt;
  #include &lt;deque&gt;
  #include &lt;iostream&gt;
  
  struct Data
  {
    std::deque&lt;int&gt; * q;
    pthread_mutex_t * mutex;
  };
  
  void* producer( void* arg )
  {
    std::deque&lt;int&gt; &amp;q = *(static_cast&lt;Data*&gt;(arg)-&gt;q);
    pthread_mutex_t * m =  (static_cast&lt;Data*&gt;(arg)-&gt;mutex);
  
    for(unsigned int i=0; i&lt;100; ++i)
    {
      pthread_mutex_lock( m );
      q.push_back( i );
      std::cout&lt;&lt;"Producing "&lt;&lt;i&lt;&lt;std::endl;
      pthread_mutex_unlock( m );
    }
    return NULL;
  }
  
  void* consumer( void * arg )
  {
    std::deque&lt;int&gt; &amp;q = *(static_cast&lt;Data*&gt;(arg)-&gt;q);
    pthread_mutex_t * m =  (static_cast&lt;Data*&gt;(arg)-&gt;mutex);
  
    for(unsigned int i=0; i&lt;100; ++i)
    {
      pthread_mutex_lock( m );
      int v = q.front();
      q.pop_front();
      std::cout&lt;&lt;"Consuming "&lt;&lt;v&lt;&lt;std::endl;
      pthread_mutex_unlock( m );
    }  
    return NULL;
  }
  
  int main()
  {
    Data d;
  
    std::deque&lt;int&gt; q;
    d.q = &amp;q;
  
    pthread_mutex_t mutex;
    pthread_mutex_init( &amp;mutex, NULL );
    d.mutex = &amp; mutex;
  
    pthread_t producer_thread;
    pthread_t consumer_thread;
  
    pthread_create( &amp;producer_thread, NULL, producer, &amp;d );
    pthread_create( &amp;consumer_thread, NULL, consumer, &amp;d );
  
    pthread_join( producer_thread, NULL );
    pthread_join( consumer_thread, NULL );
  }
  </code></pre>
  
  <p><strong>EDIT:</strong></p>
  
  <p>I did end up throwing away this implementation, I'm now using a modified version of the code from <a href="http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html" rel="nofollow noreferrer">here</a> by Anthony Williams. My modified version can be found <a href="http://gist.github.com/482342" rel="nofollow noreferrer">here</a> This modified version uses a more sensible condition variable based approach.</p>