¿El iterador final de stl map requiere protección mediante mutex o puedo desbloquearlo antes?
Tengo este código:
“`c++
std::map<std::pair<int, int>, std::string> data;
…
ContextMutex context<em>mutex( _mutex );
auto pair</em>iterator = data.find( std::make_pair(some, thing));
if(pair<em>iterator == data.end())
{
context</em>mutex.unlock();
// hacer algún registro sin utilizar pair<em>iterator
}
context</em>mutex.unlock();
“`
En este código, solo libero el mutex para mi contenedor STL después de verificar si pair_iterator == data.end()
. Me pregunto si puedo liberar el mutex antes de verificar pair_iterator == data.end()
, ya que no uso el pair_iterator
ni ninguno de sus contenidos, ya que solo imprimo un registro si se encuentra el objeto.
En este caso, ¿puedo liberar el mutex antes de verificar la condición pair_iterator == data.end()
(como en el siguiente ejemplo) o el acceso al data.end()
también necesita protección de un mutex (como se hace en el primer ejemplo)?
“`c++
std::map<std::pair<int, int>, std::string> data;
…
ContextMutex context<em>mutex( _mutex );
auto pair</em>iterator = data.find( std::make<em>pair(some, thing));
context</em>mutex.unlock();
if(pair<em>iterator == data.end())
{
// hacer algún registro sin utilizar pair</em>iterator
}
“`
Relacionado:
1. https://stackoverflow.com/questions/6438086/iterator-invalidation-rules-for-c-containers
2. https://stackoverflow.com/questions/15097778/why-do-c-stl-container-begin-and-end-functions-return-iterators-by-value-rathe
3. https://stackoverflow.com/questions/53336685/stl-iterator-revalidation-for-end-past-the-end-iterator
davy.ai
En general, acceder al iterador
end()
de un contenedor STL no requiere mantener un candado, ya que el iteradorend()
representa un elemento pasado el último y no apunta a ningún elemento real en el contenedor. Sin embargo, esto asume que ningún otro hilo está modificando el contenedor mientras se accede a él por el hilo actual.En el código proporcionado, liberar el mutex antes de comprobar si
pair_iterator == data.end()
no debería causar ningún problema, siempre y cuando el contenedor no esté siendo modificado por otro hilo concurrentemente. Una vez liberado el candado, otros hilos pueden modificar el contenedor y invalidar el iterador, por lo que cualquier uso posterior delpair_iterator
sería un comportamiento indefinido.Sin embargo, tenga en cuenta que si el contenedor es modificado por otro hilo entre la llamada a
find()
y la liberación del mutex, el iterador puede volverse inválido, lo que lleva a comportamiento indefinido si se accede a él. Para evitar esto, puede ser mejor mantener el candado hasta que se haga la comprobación dedata.end()
, o utilizar otros mecanismos de sincronización para asegurar la seguridad de los hilos.