2013-04-01 54 views
3

所以我的Enqueue和Dequeue函数如下。我如何采取我所拥有的并使其线程安全?我想过使用Windows.h中的互斥锁,但如果可能的话,我不想将我的程序限制为仅限Windows。如何使线程安全的循环队列?

void Queue::Enqueue(int num){ 
    //increase recorded size 
    size++; 
    //stick in num 
    numbers[nextSpace] = num; 
    //find the next available space 
    nextSpace = (++nextSpace) % maxSize; 
} 

int Queue::Dequeue(){ 
    int temp; 
    temp = items[curSpace]; 
    curSpace = (++curSpace) % maxSize; 
    size--; 
    return temp; 
} 
+1

为什么另起炉灶?使用Boost的'lockfree :: queue'或类似的东西。 (或'spsc_queue',相反,如果你想要一个消费者和一个生产者的循环缓冲区。) –

+0

Boost有一个可移植的同步库。请参阅http://www.boost.org/doc/libs/1_53_0/doc/html/thread/synchronization.html –

+0

您需要什么版本的“线程安全”? STL是线程安全的,你知道吗? –

回答

0

您可以参考此代码(与并行线程):

#include<pthread.h> 
#define DEFAULT_SIZE 100 
class circularQueue{ 
private: 
    int *m_queue; 
    int p_head; 
    int p_tail; 
    int m_cap; 
    pthread_mutex_t mp = PTHREAD_MUTEX_INITIALIZER; 
    public: 
     circularQueue(int size) 
     { 
      /*in case invalid input*/ 
      if(size<0) 
       size = DEFAULT_SIZE ; 

      m_queue = new int[size]; 
      p_head = 0; 
      p_tail = -1; 
      m_cap = 0; 
      pthread_mutex_init(&mp,NULL); 
     } 

     bool enqueue(int x) 
     { 
      bool res= false; 
      p_thread_mutex_lock(&mp); 
      /*queue is full*/ 
      if(m_cap == size) 
      { 
       res = false; 
      } 
      else 
      { 
       m_queue[(++p_tail)%size)] = x; 
       ++m_cap; 
       res = true; 
      } 
      p_thread_mutex_unlock(&mp); 
      return res; 
     } 
     int dequeue() 
     { 
      int res=0; 

      pthread_mutex_lock(&mp); 
      /*empty queue*/ 
      if(m_cap == 0) 
      {  
       throw("empty queue!"); 
       pthread_mutex_unlock(&mp); 
      } 
      else{ 
       res = m_queue[p_head];  
       p_head = (p_head+1)%size; 
      } 
      pthread_mutex_unlock(&mp); 
      return res; 
     }  
     ~virtual circularQueue() 
     { 
      delete[] m_queue; 
      m_queue = NULL; 
      pthread_mutex_destroy(&mp); 
     } 
} 
+0

'throw(“empty queue!”);'呈现此代码死锁 - 能够(一个线程可以锁定互斥锁,然后在不解锁的情况下抛出)。即使这是固定的,你仍然必须考虑如果适应非内置类型的赋值可能会导致同样的问题。 –