c++ - ¿Hay alguna manera de verificar si un iterador es válido?
performance stl (5)
Para dos hilos que manipulan un mapa de contenedor, por ejemplo, ¿cuál es la forma correcta de comprobar si un iterador sigue siendo válido (por razones de rendimiento)?
O sería solo de manera indirecta que esto se puede hacer. El código de muestra para esto:
#define _SECURE_SCL 1
//http://msdn2.microsoft.com/en-us/library/aa985973.aspx
#define _SECURE_SCL_THROWS 1
#include "map"
#include "string"
#include "exception"
#include "iostream"
using namespace std;
void main(void)
{
map<string, string> map_test;
map<string, string>::iterator iter_map_test;
map_test [ "AAAAA" ] = "11111";
map_test [ "BBBBB" ] = "22222";
map_test [ "CCCCC" ] = "33333";
iter_map_test = map_test.find ("BBBBB");
map_test.erase ("BBBBB");
try
{
string value = (*iter_map_test).second;
}
catch ( exception & e )
{
cout << e.what() << endl;
}
catch ( ... )
{
cout << "generic exception." << endl;
}
}
Si implementa una solución de lector / escritor, puede hacer que el escritor establezca un indicador que invalide todos los iteradores de los lectores.
http://en.wikipedia.org/wiki/Readers-writer_lock
No trataría de escribir en el mapa sin sincronización, como mencionaron Josh y Paul Tomblin.
Si sabe que uno de los hilos solo leerá el mapa mientras que el otro podría estar manipulándolo, la solución más simple es hacer que el hilo de solo lectura clone el mapa e iterar sobre el clon.
(Advertencia: sé que las clases de colección de Java son mucho mejores de lo que sé STL, pero así es como lo haría en Java).
std::map
s no son seguros para subprocesos. Tendrá problemas mucho peores que los iteradores invalidados, si tiene más de un hilo a la vez modificando el mismo mapa. Ni siquiera creo que tengas la garantía de que puedes leer algo de un mapa mientras está siendo modificado por otro hilo.
Algunas páginas sobre el STL y el subproceso:
Incluso si pudieras saber si un puntero era válido, no resolvería tu problema. Está compartiendo un solo recurso sin garantía de exlusividad. Aquí es por qué fallaría.
Fallaría en esta secuencia de hilos:
Thread0 ................................ Thread1
Obtener iterador-> it0
comprobar que it0 es válido
............................................. Obtener Iterator-> it1
............................................. Verificar que it1 sea válido .
Borrar (it0)
............................................. Borrar (it1)
Puede agregar un semáforo para acceder al recurso compartido.
Si su STL no ofrece un thread std::map
seguro, el TBB de Intel ofrece un thread_hash_map seguro para subprocesos (páginas 60 y 68).
Dejando de lado los problemas de seguridad, std::map
garantiza que las eliminaciones no invaliden los iteradores que no sean los que se eliminan. Lamentablemente, no hay un método is_iterator_valid()
para validar iteradores que tenga.
Puede ser posible implementar algo así como punteros de peligro , y TBB también tiene algunas soluciones al problema.