Renforcer la commande named_mutex et remove ()

J’ai une classe qui peut être créée par plusieurs threads. Mais au niveau d’une fonction, le code doit être protégé, j’ai donc décidé d’utiliser le mutex interprocess boost. Chaque classe crée ou ouvre le même Mutex dans son constructeur:

MyClass::MyClass() { boost::interprocess::named_mutex m_Lock( boost::interprocess::open_or_create, "myLock" ); } 

Alors maintenant, vient le point où la partie de code critique est appelée:

 int MyClass::MyFunction() { boost::interprocess::scoped_lock lock( m_Lock, boost::interprocess::try_to_lock); if(!lock) { return -1; } // else do some stuff here } 

Pour nettoyer après la fonction (et comme décrit sur la page de démarrage), j’utilise la commande remove dans mon destructeur de classe:

 MyClass::~MyClass() { boost::interprocess::named_mutex::remove("myLock"); } 

En fait, tout ce code fonctionne bien, mais il y a une préoccupation que j’ai:

Comme il est dit dans la description de la commande remove:

Efface un mutex nommé du système. Retourne false en cas d’erreur. Ne jette jamais.

Cela signifie donc que la commande remove efface simplement le Mutex du système – même si un autre thread vient de le verrouiller (j’ai déjà essayé ce cas – il n’est plus verrouillé à ce moment-là). Donc, mon problème est le suivant: Par exemple, j’ai 3 threads (A, B et C) – voici ce qui se passe:

  1. Le processus A crée une instance de la classe, appelle la fonction et la verrouille
  2. Le processus B crée une instance de la classe, appelle la fonction mais ne peut pas accéder au code (attend par exemple)
  3. Le processus A se termine avec le code protégé et il est déverrouillé
  4. Le processus B accède au code protégé et le verrouille
  5. Processus A supprime l’instance de la classe -> la commande de suppression est appelée
  6. Le processus C crée une instance de la classe, appelle la fonction et peut accéder au code puisque la commande de suppression a effacé le Mutex -> Erreur!

Alors maintenant, quelqu’un peut dire “Alors, n’appelle pas, supprime!” – C’est possible? Je veux dire puisque le named_mutex écrit dans le système, je doute qu’il soit effacé sans appel explicite, même si le programme se termine. Quelqu’un a de l’aide?

Dans les documents de démarrage , l’appel de remove est inutile. Le destructeur de named_mutex chargera automatiquement d’indiquer au système d’exploitation que le processus n’a plus besoin de la ressource. Vous pouvez probablement vous contenter de vous fier au comportement intégré du destructeur pour le nettoyage.

Si vous appelez explicitement remove, tous les processus ou threads tentant d’utiliser le mutex nommé échoueront probablement pour toutes les opérations effectuées sur le mutex. En fonction de la manière dont votre utilisation est orchestrée, cela pourrait entraîner des courses de données ou des plantages / exceptions générés par d’autres processus.

~ named_mutex ();

Détruit * this et indique que le processus appelant a fini d’utiliser la ressource. La fonction de destructeur libère toutes les ressources système allouées par le système à utiliser par ce processus pour cette ressource. La ressource peut toujours être ouverte à nouveau en appelant la surcharge du constructeur ouvert. Pour effacer la ressource du système, utilisez remove ().

Vous avez probablement besoin d’un compteur d’utilisation partagée pour le mutex. Verrouillez le mutex dans le destructeur, décrémentez-le et, s’il est égal à zéro après la décrémentation, libérez le mutex toujours verrouillé. Vous éviterez ainsi votre condition de course actuelle.