J'essaie de résoudre le problème du consommateur producteur en C++ 11. J'ai un objet qui contient des ressources, et plusieurs threads peuvent ajouter ou consommer ces ressources. Mon problème est quand j'essaie d'implémenter une méthode "consommer quand disponible" sur cet objet. Veuillez supposer que les opérations d'insertion/suppression sont d'une complexité triviale.Comment résoudre correctement le consommateur producteur en C++ 11
Une petite explication de la logique dans le code.
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;
}
}
}
};
Supposons que le scénario suivant:
-Deux fils, T1, T2, appeler addResource, getResource presque simultanément. -T2 verrouille le mutex et découvre qu'il n'y a plus de ressources disponibles,
donc il doit bloquer jusqu'à ce qu'une nouvelle ressource soit disponible.
Donc, il déverrouille le mutex et met en place la cloche d'attente.
-T1 exécute une correspondance plus rapide. Lorsque le mutex est déverrouillé, il ajoute immédiatement la ressource, et avant que T2 ne mette en place la cloche d'attente,
T1 a déjà sonné la cloche, qui n'indique personne.
-T2 attend indéfiniment que la cloche sonne, mais aucune autre ressource n'est ajoutée.
Je fais l'hypothèse qu'un fil bloquant un mutex, peut être le seul pour le déverrouiller. Donc, si j'essayais d'appeler bell.wait avant de déverrouiller le mutex, le mutex ne pourrait jamais être déverrouillé.
Je ne souhaite pas utiliser de solution d'attente ou de vérification multiple si possible.
Alors, comment pourrais-je résoudre ce problème en C++ 11?
Peut-être pas lié à votre problème, mais s'il vous plaît utiliser des gardes de verrouillage comme 'std :: unique_lock' pour le verrouillage/déverrouillage des mutex. –
lock est un unique_lock –
Qu'est-ce que 'wmux'? Vous devriez verrouiller 'lock', et effectuer' bell.wait (lock) ', pour éviter une condition de concurrence. – erenon