C++ 11でプロデューサコンシューマの問題を解決しようとしています。 リソースを保持するオブジェクトがあり、複数のスレッドでこれらのリソースを追加または使用することができます。 私の問題は、私が を実装しようとしたときに、そのオブジェクトに対して「利用可能なときに消費する」メソッドです。 挿入/削除操作が複雑ではないと仮定してください。C++でプロデューサコンシューマを正しく解決する方法11
ロジックの説明が少しあります。ほぼ同時にaddResource、のgetResourceを呼び出し、
- 2つのスレッド、T1、T2:
struct ResourceManager{
std::mutex mux;
std::unique_lock lock{mux};
std::condition_variable bell;
void addResource(/*some Resource*/){
lock.lock();
//add resource
lock.unlock();
bell.notify_one(); //notifies waiting consumer threads to consume
}
T getResource(){
while(true){
lock.lock();
if(/*resource is available*/){
//remove resource from the object
lock.unlock();
return resource;
}else{
//new unique lock mutex object wmux creation
lock.unlock(); //problem line
bell.wait(wmux); //waits until addResource rings the bell
continue;
}
}
}
};
次のシナリオを仮定する。
-T2はmutexをロックし、使用可能なリソースがもうないことを確認します。
したがって、新しいリソースが利用可能になるまでブロックする必要があります。
これでミューテックスのロックが解除され、ベル待機を設定します。
-T1がより速くマッチします。ミューテックスがロックされていない場合、
はすぐにリソースを追加し、T2は待機中のベルを設定する前に、
T1は既にベルを鳴らし、誰にも通知しません。
-T2は、ベルが鳴るのを無期限に待機しますが、リソースは追加されません。
私は、mutexをロックしているスレッドがロックを解除する唯一のものであるかもしれないと仮定しています。したがって、mutexのロックを解除する前にbell.waitを呼び出そうとすると、 ミューテックスをロック解除することはできません。
可能であれば、時間待機型または複数回のチェックソリューションを使用しません。
C++ 11でこの問題をどのように解決できますか?
あなたの問題には関係ないかもしれませんが、mutexのロック/ロック解除には 'std :: unique_lock'のようなロックガードを使用してください。 –
ロックはunique_lockです –
'wmux'とは何ですか?競合状態を避けるには、 'lock'をロックし、' bell.wait(lock) 'を実行する必要があります。 – erenon