J'ai une application multithread qui doit souvent lire certaines données, et parfois ces données sont mises à jour. À l'heure actuelle, un mutex garde l'accès à ces données en toute sécurité, mais c'est cher car j'aimerais que plusieurs threads puissent lire simultanément et ne les verrouiller que lorsqu'une mise à jour est nécessaire (le thread de mise à jour pourrait attendre que les autres threads se terminent) .
Je pense que c'est ce qui boost::shared_mutex
est censé faire, mais je ne sais pas comment l'utiliser et je n'ai pas trouvé d'exemple clair.
Quelqu'un a-t-il un exemple simple que je pourrais utiliser pour commencer?
c++
multithreading
boost
mutex
boost-thread
kevin42
la source
la source
Réponses:
Il semble que vous feriez quelque chose comme ceci:
la source
1800 INFORMATION est plus ou moins correct, mais il y a quelques problèmes que je voulais corriger.
Notez également, contrairement à un shared_lock, un seul thread peut acquérir un upgrade_lock à la fois, même s'il n'est pas mis à niveau (ce que j'ai trouvé gênant lorsque je l'ai rencontré). Donc, si tous vos lecteurs sont des écrivains conditionnels, vous devez trouver une autre solution.
la source
boost::unique_lock< boost::shared_mutex > lock(lock);
lireboost::unique_lock< boost::shared_mutex > lock(
_access);
?Depuis C ++ 17 (VS2015), vous pouvez utiliser la norme pour les verrous en lecture-écriture:
Pour les anciennes versions, vous pouvez utiliser boost avec la même syntaxe:
la source
typedef boost::unique_lock< Lock > WriteLock; typedef boost::shared_lock< Lock > ReadLock;
.Juste pour ajouter quelques informations empiriques, j'ai étudié toute la question des verrous évolutifs, et Exemple pour boost shared_mutex (plusieurs lectures / une écriture)? est une bonne réponse en ajoutant les informations importantes selon lesquelles un seul thread peut avoir un upgrade_lock même s'il n'est pas mis à niveau, ce qui est important car cela signifie que vous ne pouvez pas passer d'un verrou partagé à un verrou unique sans libérer le verrou partagé au préalable. (Cela a été discuté ailleurs, mais le fil le plus intéressant est ici http://thread.gmane.org/gmane.comp.lib.boost.devel/214394 )
Cependant, j'ai trouvé une différence importante (non documentée) entre un thread en attente d'une mise à niveau vers un verrou (c'est-à-dire qu'il doit attendre que tous les lecteurs libèrent le verrou partagé) et un verrou d'écriture en attente de la même chose (c'est-à-dire un unique_lock).
Le thread qui attend un unique_lock sur shared_mutex bloque tout nouveau lecteur entrant, ils doivent attendre la demande des rédacteurs. Cela garantit aux lecteurs de ne pas affamer les écrivains (mais je crois que les écrivains pourraient affamer les lecteurs).
Le thread qui attend un upgrade_lock pour mettre à niveau permet à d'autres threads d'obtenir un verrou partagé, donc ce thread pourrait être affamé si les lecteurs sont très fréquents.
C'est une question importante à prendre en compte et devrait probablement être documentée.
la source
Terekhov algorithm
garantit que1.
l'écrivain ne peut pas affamer les lecteurs. Regarde ça . Mais2.
c'est vrai. Un upgrade_lock ne garantit pas l'équité. Regarde ça .Utilisez un sémaphore avec un nombre égal au nombre de lecteurs. Laissez chaque lecteur prendre un compte du sémaphore afin de lire, de cette façon ils peuvent tous lire en même temps. Ensuite, laissez l'écrivain prendre TOUS les comptes de sémaphore avant d'écrire. Cela oblige l'enregistreur à attendre la fin de toutes les lectures, puis à bloquer les lectures lors de l'écriture.
la source
Excellente réponse de Jim Morris, je suis tombé dessus et il m'a fallu un certain temps pour comprendre. Voici un code simple qui montre qu'après avoir soumis une "requête" pour un boost unique_lock (version 1.54) bloque toutes les requêtes shared_lock. Ceci est très intéressant car il me semble que le choix entre unique_lock et upgradeable_lock permet si nous voulons une priorité d'écriture ou aucune priorité.
Aussi (1) dans le message de Jim Morris semble contredire ceci: Boost shared_lock. Lire préféré?
la source