私はマルチスレッドについて学習しています。私はそれを呼び出すことができればセマフォを使用してプロデューサ/コンシューマの問題をシミュレートしたかったのです。Segfaultが待ち行列を同期しようとしています
キューを保持するクラスがあり、プロデューサはキューにintsをプッシュし、コンシューマはキューを取得して印刷します。私がシミュレートさ
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);
}
}
したがって、ユーザーのプレス2つのスレッドがある場合は、ユーザー入力1、データは、キューの中に押し込まれたとき生まれた
たとえば、1 1と2、または2 1 1 を押すと、segfaultがスローされます。私のコードの理解がなぜ次のようになっているのか分かりません。2 1 1
私は5つのスレッドを初期化します。キューは空で、スリープ状態になります。番号をキューにプッシュすると、スリープ中のすべてのスレッドに通知されます。 ロックミューテックスをもう一度起動してキューから番号を取得し、その後ミューテックスをリリースすると、ミューテックスが解放されたとき別のスレッドが同じことを行い、ミューテックスをロック解除します.3番目のスレッドはロックされていません。そのキューは再び空であり、残りのスレッドと同じように再びスリープ状態になります。
この論理は正しいですか?もしそうなら、なぜこれがsegfaultを投げつけているのですか?そうでなければ、私はすべての説明を感謝します。
ありがとうございました!
//編集 答え:suggets、私は[]をvector.push_backに置き換えましたが、消費者は今データに何もせず、受け取ったり印刷したりしません。
typo、ありがとう!それを更新しました – Darlyn
ああ、ありがとうagain :) – Darlyn