我正在學習關於多線程的,我想模擬生產者消費者問題(使用旗語如果我可以稱呼它)。段錯誤發生的歷史同步隊列
我有一個持有隊列,製片人推到整數隊列類和消費類檢索它並打印。我模擬是如下
class TestClass{
public:
void producer(int i){
unique_lock<mutex> l(m);
q.push(i);
if(q.size())
cnd.notify_all();
}
void consumer(){
unique_lock<mutex> l(m);
while(q.empty()){
cnd.wait(l);
}
int tmp = q.front();
q.pop();
cout << "Producer got " << tmp << endl;
}
void ConsumerInit(int threads){
for(int i = 0; i < threads; i++){
thrs[i] = thread(&TestClass::consumer, this);
}
for(auto &a : thrs)
a.join();
}
private:
queue<int> q;
vector<thread> thrs;
mutex m;
condition_variable cnd;
};
我使用的小控制檯應用程序來調用數據:
int main(){
int x;
TestClass t;
int counter = 0;
while(cin >> x){
if(x == 0)
break;
if(x == 1)
t.producer(counter++);
if(x == 2)
t.ConsumerInit(5);
}
}
因此,當用戶輸入1,數據被推入隊列中,如果用戶按2個線程是催生。
以任何順序調用它,例如,按下1 1然後2或2 1 1 它會拋出段錯誤。我不知道爲什麼我的我的代碼的理解如下:假設爲了2 1 1
我初始化5個線程,他們看到隊列爲空,所以他們去睡覺。當我向隊列中推送一個號碼時,它會通知所有睡眠的線程。 第一個喚醒再次鎖定互斥體,然後繼續從隊列中檢索數字,然後釋放互斥體,當互斥體釋放時,另一個線程完成相同的操作並解鎖互斥體,互斥體解鎖後的第三個線程仍處於循環狀態,請參閱該隊列再次爲空,並再次進入休眠狀態,與所有剩餘的線程一樣。
是這個邏輯是否正確?如果是這樣,爲什麼這樣的扔段錯誤,如果沒有,我感謝所有的解釋。
感謝您的幫助!
//編輯 通過回答suggets,我用vector.push_back替換了[],但是消費者現在對數據不做任何處理,不會接受或打印它。
錯字,謝謝!更新它 – Darlyn
哦,再次感謝:) – Darlyn