2012-02-16 39 views
6

Estoy usando std :: vector como datos compartidos en una aplicación multiproceso. I encapsular el hilo dentro de una clase, por ejemplo,std :: vector, thread-safety, multi-threading

class ABC { 
public: 
    double a, b, c; 
}; 

boost::mutex mutex1; 

class XYZ { 
public: 
    XYZ(vector<ABC> & pVector) { 
     ptrVector = &pVector; 
     m_thread = boost::thread(&XYZ::Start, this); 
    } 
    ~XYZ() {} 
    void Start(); 
public: 
    vector<ABC> * ptrVector; 
    boost::thread m_thread; 
};  

void XYZ::Start() { 
    try { 
     while(1) { 
      boost::this_thread::interruption_point(); 
      for (unsigned int i=0; i<ptrVector->size(); i++) { 
       { 
        boost::mutex::scoped_lock lock(mutex1); 
        ptrVector->at(i).a = double(rand())/10000; 
        ptrVector->at(i).b = double(rand())/10000; 
        ptrVector->at(i).c = double(rand())/10000; 
       } 
      } 
     } 
    } 
    catch(boost::thread_interrupted) {} 
    catch(std::exception) {} 
} 

Al cerrar la aplicación, veces, en la depuración, habrá 2 mensajes de error, veces habrá ningún mensaje de error. A menudo escuché gente hablando de que std :: vector no es seguro para subprocesos, ¿es este uno de los casos? Estoy usando Visual Studio 2008, aumentar el hilo, el tamaño del vector es fijo. ¿Alguien puede ofrecer también algunos consejos sobre cómo usar std :: vector en una aplicación multiproceso?

  1. excepción de primera oportunidad en 0x7688b9bc en ETP.exe: Microsoft C++ excepción: std :: out_of_range en la posición de memoria 0x02d8f7bc ..
  2. excepción de primera oportunidad en 0x00e916e0 en ETP.exe: 0xc0000005: Acceso ubicación de lectura de violación 0x00000008.
  3. la segunda oportunidad de aserción: El archivo c: \ archivos de programa (x86) \ Microsoft Visual Studio 9.0 \ VC \ include vector \, línea Segunda Probabilidad de aserción: El archivo c: \ archivos de programa (x86) \ Microsoft visual estudio 9.0 \ vc \ include \ vector98

Gracias.

+0

vector no se hilo de seguridad, si se intenta escribir en él al mismo tiempo desde diferentes hilos y luego se romperá. Sin embargo, lo está bloqueando, y sin otro código para ver cómo lo está usando, es imposible determinar qué podría estar yendo mal. Este código particular en sí mismo se ve bien. – Jarryd

+0

Además de la seguridad del hilo, probablemente también deba tener en cuenta la secuencia en la que sus hilos acceden al vector. Si un hilo está leyendo del vector, debe asegurarse de que el otro hilo haya escrito en el vector anterior o al menos su El código debe manejar la condición de que el vector no se haya escrito. –

+0

@Jarryd usted es rito, en este código parece que está bloqueando el vector usando mutex, si lo hace, entonces no debería causar problema, para más detalles tenemos que ir a través del código completo –

Respuesta

22

En realidad, es absolutamente inútil al estado X es o no es seguro para subprocesos! Necesita calificar para qué tipo de usos. Por ejemplo, casi ninguna clase será "segura para subprocesos" cuando de alguna manera se usa en un subproceso y se destruye en otro.

Dicho esto, la afirmación de que std::vector<T> no es seguro para hilos, independientemente de la frecuencia con que se repita, es incorrecto. Sin embargo, parece que la mayoría de la gente no entiende ni aprecia las garantías de seguridad de hilos dadas. std::vector<T> es seguro para subprocesos en el siguiente sentido:

  • Puede leer un objeto vectorial desde múltiples subprocesos simultáneamente.
  • Si hay un hilo que cambia un objeto vectorial, no habrá lectores o escritores concurrentes.
  • Los accesos a un objeto vectorial no interfieren con otros objetos vectoriales.

Esto se aplica a la estructura vectorial en sí. Los accesos al objeto contenido están sujetos a las reglas que se les impongan. Estas aparentemente no son las garantías de seguridad de hilos que mucha gente tiene en mente, pero cualquier cosa más fuerte no funcionará con la interfaz del contenedor.

+0

gracias por el consejo. Ahora es mucho más claro para mí. – 2607

+0

Lo sentimos, pero totalmente en desacuerdo contigo, thread-safe es una definición conocida que establece que la implementación debe garantizar la concurrencia (hilo) protegiendo las áreas compartidas para evitar conflictos, esto significa que una clase es segura o no, indicando que depende del uso significa que no es seguro para subprocesos, ¿cómo puede ser esta la respuesta correcta? – Cross

+0

Puede leer múltiples hilos simultáneamente. Sí, siempre y cuando se haya producido una barrera de memoria de liberación después de su última modificación y se haya producido una barrera de memoria de adquisición coincidente en todos los hilos de lectura ... – Persixty

4

Llama a ptrVector->size() sin antes bloquearlo. Esto podría ser la causa de tus problemas. Asegúrese de bloquear su vector antes de leer o escribir.

+1

Dijo que el tamaño de el vector es fijo, por lo que no debería causar un problema. Sin embargo, dado que no tenemos más código, no sabemos si lo está agregando de una manera insegura sin saberlo. – Jarryd