¿Debo proteger el acceso de lectura a un contenedor STL en un entorno de subprocesos múltiples?

Tengo un contenedor std :: list y estos hilos:

Hay un mutex normal que protege el acceso a la lista de los primeros dos hilos. Mi pregunta es, ¿los hilos del lector de tamaño necesitan adquirir este mutex también? ¿Debo usar un mutex de lectura / escritura?

Estoy en un entorno de Windows con Visual C ++ 6.

Actualización : Parece que la respuesta aún no está clara. Para resumir la duda principal: ¿Todavía necesito proteger los hilos del lector de TAMAÑO incluso si solo llaman a size () (que devuelve una variable simple) teniendo en cuenta que no necesito el valor exacto (es decir, puedo suponer una +/- 1 variación)? ¿Cómo una condición de carrera podría hacer que mi llamada a size () devuelva un valor no válido (es decir, uno totalmente ajeno al bueno)?

Respuesta : En general, los hilos del lector deben estar protegidos para evitar condiciones de carrera. Sin embargo, en mi opinión, algunas de las preguntas mencionadas anteriormente en la actualización aún no han sido respondidas.

¡Gracias por adelantado!

¡Gracias a todos por sus respuestas o comentarios!

Sí, los hilos de lectura necesitarán algún tipo de control mutex, de lo contrario, la escritura cambiará cosas de debajo.

Un mutex de lector / escritor debería ser suficiente. Pero estrictamente hablando, este es un problema específico de la implementación. Es posible que una implementación tenga miembros mutables incluso en objetos const que sean de solo lectura en su código.

Verifique los contenedores simultáneos proporcionados por la biblioteca de bloques de creación de código abierto de Intel. Consulte algunos ejemplos en “Fragmentos de contenedor” en la página Ejemplos de código . Tienen contenedores concurrentes / hilos seguros para vectores, mapas hash y colas.

No creo que los contenedores STL sean seguros para subprocesos, ya que no hay una buena manera de manejar subprocesos multiplataforma. La llamada al tamaño () es simple, pero aún necesita protección.

Esto suena como un gran lugar para usar lockings de lectura y escritura.

Debería considerar que alguna implementación de SLT podría calcular el tamaño cuando se le llama.
Para superar esto, podría definir una nueva variable

volatile unsigned int ContainerSize = 0; 

Actualice la variable solo dentro de las llamadas de actualización ya protegidas, pero puede leer / probar la variable sin protección (teniendo en cuenta que no necesita el valor exacto).

Sí. Sugiero que envuelva su biblioteca STL con una clase que implique el acceso en serie. O encuentre una clase similar que ya haya sido depurada.

Voy a decir que no. En este caso.

Sin un mutex, lo que puede encontrar es que el tamaño () devuelve el valor incorrecto ocasionalmente, a medida que se agregan o eliminan elementos. Si esto es aceptable para ti, ve por ello.

Sin embargo, si necesita el tamaño preciso de la lista cuando el lector necesita saberla, tendrá que incluir una sección crítica en cada llamada de tamaño además de la que tiene alrededor de las llamadas de agregar y borrar.

PD. El tamaño VC6 () simplemente devuelve el miembro interno _Size, por lo que no tener un mutex no será un problema con su implementación particular, excepto que podría devolver 1 cuando se agrega un segundo elemento, o viceversa.

PPS. alguien mencionó un locking RW, esto es algo bueno, especialmente si está tentado de acceder a la lista de objetos más tarde. Cambie su mutex a un Boost :: shared_mutex sería beneficioso entonces. Sin embargo, no se necesita mutex alguno si todo lo que llamas es de tamaño ().

El STL en VC ++ versión 6 no es seguro para subprocesos, consulte esta pregunta reciente . Entonces parece que tu pregunta es un poco irrelevante. Incluso si hiciste todo bien, es posible que todavía tengas problemas.

Si el tamaño () es seguro (para la definición de “seguro” que proporciona) depende de la implementación. Incluso si está cubierto en su plataforma, para su versión de comstackdor en su nivel de optimización para su versión de la biblioteca de subprocesos y C runtime, no codifique de esta manera. Volverá a byte, y será un infierno para depurar. Te estás preparando para el fracaso.