2013-04-01 82 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!」);'呈現此代碼死鎖 - 能夠(一個線程可以鎖定互斥鎖,然後在不解鎖的情況下拋出)。即使這是固定的,你仍然必須考慮如果適應非內置類型的賦值可能會導致同樣的問題。 –