push_back libreria iterador español c++ multithreading visual-c++ stl concurrency

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



push_back c++ (8)

Tengo un contenedor std :: list <> y estos hilos:

  • Un hilo de escritor que agrega elementos indefinidamente.

  • Un hilo de lector / escritor que lee y elimina elementos mientras está disponible.

  • Varios hilos de lectura que acceden al TAMAÑO del contenedor (utilizando el método size ())

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!


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 bloqueos de lectura y escritura.


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.


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.


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.


Voy a decir que no. En este caso.

Sin un mutex, lo que puede encontrar es que el tamaño () devuelve el valor incorrecto de vez en cuando, ya que los elementos se agregan o eliminan. 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 bloqueo 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 size ().


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).


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 compilador 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.


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.