title: Is volatile variables safe in one customer thread and one producer thread?
body: <p>is this code correct? I see this code in someone's blog, it said that <strong>volatile</strong> is safe in environment of only one customer and only one producer. I don't know if it's really thread-safe.</p>
  
  <p>the code is following:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;pthread.h&gt;
  
  
  template&lt;class QElmType&gt;
  struct qnode
  {
      struct qnode *next;
      QElmType data;
  };
  template&lt;class QElmType&gt;
  class queue
  {
  public:
          queue() {init();}
          ~queue() {destroy();}
  
          bool init()
          {
                  m_front = m_rear = new qnode&lt;QElmType&gt;;
                  if (!m_front)
                          return false;
                  m_front-&gt;next = 0;
                  return true;
          }
          void destroy()
          {
                  while (m_front)
                  {
                          m_rear = m_front-&gt;next;
                          delete m_front;
                          m_front = m_rear;
                  }
          }
          bool push(QElmType e)
          {
                  struct qnode&lt;QElmType&gt; *p = new qnode&lt;QElmType&gt;;
                  if (!p)
                          return false;
                  p-&gt;next = 0;
                  m_rear-&gt;next = p;
                  m_rear-&gt;data = e;
                  m_rear = p;
                  return true;
          }
          bool pop(QElmType *e)
          {
                  if (m_front == m_rear)
                          return false;
  
  
                  struct qnode&lt;QElmType&gt; *p = m_front;
                  *e = p-&gt;data;
                  m_front = p-&gt;next;
                  delete p;
                  return true;
          }
  private:
    struct qnode&lt;QElmType&gt; * volatile m_front, * volatile m_rear;
  };
  
  
  queue&lt;int&gt; g_q;
  
  
  void *thread1(void * l)
  {
          int i = 0;
          while (1)
          {
                  g_q.push(i);
                  i++;
                  usleep(::rand()%1000);
          }
          return 0;
  }
  void *thread2(void * l)
  {
          int i;
          while (1)
          {
                  if (g_q.pop(&amp;i))
                          std::cout &lt;&lt; i &lt;&lt; std::endl;
                  //else
                          //std::cout &lt;&lt; "can not pop" &lt;&lt; std::endl;
                  usleep(::rand()%1000);
          }
          return 0;
  }
  
  
  int main(int argc, char* argv[])
  {
          pthread_t t1,t2;
          pthread_create(&amp;t1, 0, thread1, 0);
          pthread_create(&amp;t2, 0, thread2, 0);
          char ch;
          while (1)
          {
                  std::cin &gt;&gt; ch;
                  if (ch == 'q')
                          break;
          }
         return 0;
  }
  </code></pre>