2013-04-10 83 views
0

我試圖做一個簡單的程序,以瞭解線程和併發在C++中。我創建了一個名爲MyQueue的模板類,它實現了一個隊列和一些變量來處理線程的同步。C++:deque的迭代器不dereferencable

類只有兩個函數來獲取,並把項目從隊列和一個函數來關閉隊列,並避免進一步的訪問。

程序編譯得很好,但在調試時,它得到了以下錯誤:

表達:deque的迭代器不dereferencable

這可不管什麼線程正在做的發生,如果get或put項目。

下面是代碼:

template <class T> class MyQueue{ 
queue<T> myqueue; 
int N; 
bool open; 
mutex m,m_open; 
condition_variable cv,cv2; 

public: 
MyQueue(int size){ 
    N=size; 
    open=true; 
} 

bool isOpen(){ 
    lock_guard<mutex> lg(m_open); 
    return open; 
} 

void close(){ 
    lock_guard<mutex> lg(m_open); 
    open=false; 
    cv.notify_all(); 
    cv2.notify_all(); 
} 

bool get(T &t){ 
    if(isOpen()==false)return false; 
    if(myqueue.size()>0){ 
     { 
      lock_guard<mutex> lg(m); 
      t=myqueue.front(); 
      myqueue.pop(); 
      cv.notify_one(); 
     } 
    }else{ 
     unique_lock<mutex> ul(m); 
     cv2.wait(ul); 
     if(!isOpen()) return false; 
     t=myqueue.front(); 
     myqueue.pop(); 
     cv.notify_one(); 
    } 
    return true; 
} 



bool put(T t){ 
    if(!isOpen())return false; 
    if(myqueue.size()<N){ 
     { 
     lock_guard<mutex> lg(m); 
     myqueue.push(t); 
     cv2.notify_one(); 
     } 
    }else{ 
     unique_lock<mutex> ul(m); 
     cv.wait(ul); 
     if(!isOpen())return false; 
     myqueue.push(t); 
     cv2.notify_one(); 
    } 
    return true; 
} 

}; 
+1

你通常得到,當你試圖derefrence一個無效指針錯誤,請確保您的隊列中有數據和迭代器試圖遵從之前有效。 – dchhetri 2013-04-10 18:23:13

+0

線程是邪惡的,但你測試大小之前並不需要一個鎖?你可以測試規模,發現它是一個但在此之前,你可以刪除任何其他線程已經到來,並且在隊列中刪除的唯一項目。 – john 2013-04-10 18:26:41

+0

@john線程不是邪惡的。他們無動於衷。 :) – 2013-04-10 18:35:34

回答

0

我解決了這個由等待改變get和put函數來wait_for。 例如,在得到:

if(!cv.wait_for(lock, std::chrono::milliseconds(2100), [this] { return !myQueue.empty();})) return false;

這樣線程等待一段時間,只是設定量調用myQueue.empty()並不需要一個適當的鎖(如答案的建議)。