Mise à niveau de boost :: shared_lock vers un verrou exclusif

Quelqu’un pourrait-il s’il vous plaît expliquer l’utilisation correcte de boost :: upgrade_lock. Le code suivant entraîne un blocage

//Global typedef boost::shared_mutex Mutex; typedef boost::shared_lock ReadLock; typedef boost::upgrade_lock UpgradeLock; typedef boost::upgrade_to_unique_lock WriteLock; Mutex sharedMutex; //Multi threaded reader and writer { ReadLock read(sharedMutex); for (int ii = 0; ii < vec.size(); ++ii) { Element e = vec[ii]; if (e.needsUpdating()) { UpgradeLock upgrade(sharedMutex); WriteLock write(upgrade) //Do stuff } } } 

Il ne se bloque pas si je déverrouille le verrou de lecture avec read.unlock () avant la mise à niveau. Mais il semble que cela ne devrait pas être nécessaire?

Dans la classe boost::shared_mutex (qui implémente le concept UpgradeLockable), un seul thread ne doit pas tenter d’acquérir à la fois un verrou partagé et un verrou pouvant être mis à niveau (ou unique). À tout moment, UpgradeLockable peut disposer de N verrous partagés (via lock_shared ) et d’un verrou lock_upgrade mis à niveau (via lock_upgrade ). Le verrou extensible peut demander qu’il devienne un verrou unique, qui bloque jusqu’à ce qu’il devienne le détenteur exclusif, ce qui nécessite que tous les verrous partagés soient libérés. Il est impossible de convertir un verrou partagé en un verrou unique ou un verrou partagé en un verrou pouvant être mis à niveau sans libérer le verrou partagé au préalable.

Notez que le verrou pouvant être mis à niveau n’est pas exclusif (d’autres verrous partagés peuvent être conservés), mais qu’il dispose de privilèges spéciaux pour augmenter sa résistance. Malheureusement, plusieurs threads pouvant être mis à niveau ne sont pas autorisés en même temps.

Dans votre cas, le même thread tente d’utiliser lock_shared et lock_upgrade , ce qui entraînera un blocage. Vous pouvez le réécrire comme ci-dessous, sans déblocage, mais il s’agit toujours d’un sharepoint discorde pour tous les lecteurs, dans la mesure où seul 1 verrouille le locking de la mise à niveau à la fois. Dans ce cas, selon vos autres fonctions, la complexité d’un shared_mutex pourrait ne pas être nécessaire. Toutefois, si d’autres fonctions acquièrent toujours des verrous partagés, les opérations ci-dessous fonctionneront comme prévu.

 //Multi threaded reader and writer { // Only 1 thread can pass this. Other shared locks are also valid UpgradeLock read(sharedMutex); for (int ii = 0; ii < vec.size(); ++ii) { Element e = vec[ii]; if (e.needsUpdating()) { // Blocks here until all shareds are released WriteLock write(upgrade) //Do stuff } } }