En la clase boost::shared_mutex
(que implementa el concepto UpgradeLockable), un hilo único no debe intentar adquirir tanto un bloqueo compartido como uno actualizable (o único). En cualquier momento, UpgradeLockable puede tener N bloqueos compartidos retenidos (a través de lock_shared
) y 1 bloqueo actualizable (a través del lock_upgrade
). El bloqueo actualizable puede solicitar que se convierta en un bloqueo único, que bloquea hasta que pueda convertirse en titular exclusivo, lo que requiere que se liberen todos los bloqueos compartidos. Es imposible convertir un bloqueo compartido en un bloqueo único o un bloqueo compartido en un bloqueo actualizable sin liberar el bloqueo compartido primero.
Nota: el bloqueo actualizable no es exclusivo (se pueden retener otros bloqueos compartidos) solo porque tiene privilegios especiales para aumentar su fortaleza. Lamentablemente, no se permiten varios subprocesos actualizables al mismo tiempo.
En su caso, el mismo hilo está intentando usar lock_shared
y lock_upgrade
, lo que hará que se bloquee. Puede volver a escribirlo como se muestra a continuación, y no se estancará, pero sigue siendo un punto único de contención para todos los lectores, ya que solo 1 mantendrá el bloqueo de actualización a la vez. En ese caso, dependiendo de sus otras funciones, la complejidad de un shared_mutex podría no ser necesaria. Sin embargo, si otras funciones todavía están adquiriendo bloqueos compartidos, entonces lo siguiente funcionará como espera.
//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
}
}
}
Desafortunadamente necesito varios lectores para poder ingresar al bucle al mismo tiempo, por lo que no puedo usar un bloqueo de actualización. Gracias por la explicación. –