¿Stl vector concurrente es seguro para subprocesos?

Estoy trabajando en una aplicación donde se espera que una gran cantidad de subprocesos iteren sobre un conjunto de valores de cadena e intenten unir sus propios datos con los datos disponibles en la lista.

Estoy buscando el siguiente caso de uso:

  1. El vector se inicializa con algunos elementos del tipo std :: string. (Digamos que el nombre del objeto es strList). strList se inicializará en el momento del inicio de la aplicación.
  2. Todos los hilos se iterarán sobre strList para ver si su valor coincide con al menos un elemento de strList.
  3. Ningún hilo intentará modificar strList y se usará estrictamente como un objeto de solo lectura.

Entonces, ¿podría decirme si las lecturas concurrentes son seguras para subprocesos en objetos vectoriales? Estoy usando RHEL 6 y la versión de gcc es 4.5.x

para el escenario que mencionas, es perfectamente Thread Safe.


En realidad, STL no es una forma correcta de referirlo.
Es la biblioteca estándar de C ++ .

El estándar C ++ 03 no habla de simultaneidad, por lo que el aspecto de concurrencia se omite como un detalle de implementación para los comstackdores. Entonces, la documentación que viene con su comstackdor es donde debería buscar respuestas relacionadas con la concurrencia.

La mayoría de las implementaciones de STL no son seguras para hilos como tal.
Pero para las lecturas simultáneas del mismo objeto de varios subprocesos, la mayoría de las implementaciones de STL son seguras para hilos.

Referencias

MSDN dice:

Un solo objeto es seguro para la lectura de subprocesos múltiples. Por ejemplo, dado un objeto A, es seguro leer A desde el hilo 1 y desde el hilo 2 simultáneamente.

La documentación Dinkumware STL dice:

Múltiples hilos pueden leer con seguridad el mismo objeto contenedor. (Hay subobjetos mutables no protegidos dentro de un objeto contenedor).

La documentación de GCC dice:

Actualmente usamos la definición de seguridad de hilos de SGI STL , que establece:

La implementación SGI de STL es segura para subprocesos únicamente en el sentido de que los accesos simultáneos a distintos contenedores son seguros, y los accesos de lectura simultáneos a contenedores compartidos son seguros. Si varios subprocesos tienen acceso a un único contenedor, y al menos un subproceso puede potencialmente escribir, entonces el usuario es responsable de garantizar la exclusión mutua entre los subprocesos durante los accesos al contenedor.

Por lo tanto, a partir de lo anterior, sí es seguro para subprocesos en GCC tener lecturas concurrentes del mismo objeto de múltiples subprocesos.

Nota: La biblioteca estándar de GCC es una derivada del código STL de SGI.

Hay una mención específica en C ++ 0x FDIS (n3290) para esto.

§ 17.6.5.9 Evitación de raza de datos

El párrafo completo es de interés, pero más particularmente:

3 / Una función de biblioteca estándar de C ++ no modificará directa o indirectamente los objetos (1.10) accesibles por hilos que no sean el hilo actual a menos que se acceda a los objetos directa o indirectamente mediante los argumentos no const de la función, incluido esto.

significa que puede llamar a cbegin y cend en std::vector forma segura. Además de llamar al operator== u operator< en std::string .

6 / Las operaciones en los iteradores obtenidos llamando a un contenedor de biblioteca estándar o una función miembro de cadena pueden acceder al contenedor subyacente, pero no deben modificarlo.

significa que simplemente iterar sobre un contenedor no debe modificar dicho contenedor de ninguna manera.

Sin embargo, a pesar de 3 / , parece haber espacio para los objetos globales, ya que los iteradores modifican algún tipo de objeto de registro compartido en el que se asociarían con el contenedor (características de depuración de STL). No tengo sentido de:

7 / Las implementaciones pueden compartir sus propios objetos internos entre hilos si los objetos no son visibles para los usuarios y están protegidos contra carreras de datos.

de otra manera.

De todos modos, el Estándar garantiza que la iteración sobre el vector será segura ... pero no da garantías cuando se trata de leer realmente los objetos (esos son los suyos). En este caso, esto está cubierto porque std::string está cubierto arriba.

EDITAR: Como David Hammen señaló con justicia, este Estándar aún no se ha implementado por completo. Muchos comstackdores ya proporcionaron las garantías anteriores, a pesar de que el estándar anterior nunca habló sobre los hilos. MSVC, gcc, clang, icc, comeau, etc ... Todos los grandes nombres ya deberían proporcionar esta garantía, como se puede ver en la respuesta de Als.

Además de las reglas genéricas sobre la evitación de la raza de datos, en [container.requirements.dataraces] el estándar dice

-1- Con el fin de evitar razas de datos (17.6.5.9), las implementaciones deben considerar las siguientes funciones como const : begin , end , rbegin , rend , front , back , data , find , lower_bound , upper_bound , equal_range , at y excepto en contenedores asociativos asociativos o desordenados, operator[] .

Por lo tanto, incluso si llama a no-const begin() / end() etc. siempre y cuando no modifique nada, es seguro.