2010-12-09 12 views
11

Estoy usando Android 2.2, que viene con una versión de STLport. Por algún motivo, se configuró para que no sea seguro para subprocesos. Esto se hizo usando #define _NOTHREADS en un archivo de encabezado de configuración.¿C++ STL es seguro para subprocesos para contenedores distintos (mediante la implementación de STLport)?

Cuando construí e inicialicé distintos contenedores no compartidos (por ejemplo, cadenas) de diferentes pthreads, recibí daños en la memoria.

Con _NOTHREADS, parece que algún código de bajo nivel en AWL dentro de allocator.cpp no ​​hace el bloqueo adecuado. Parece análogo a C no proporcionar seguridad de hilo para malloc.

¿Alguien sabe por qué STL podría construirse con _NOTHREADS por defecto en Android? Al apagar esto, me pregunto si puede haber un efecto secundario. Una cosa en la que puedo pensar es en el rendimiento ligeramente degradado, pero no veo mucha opción, dado que estoy usando muchos subprocesos.

+0

Podría ayudar a las personas a responder a su pregunta si usted dio algún código de muestra que mostrara el tipo de cosas que conducen al problema. (Sé que * I * no tengo la experiencia necesaria para responder a esto; el STL no es algo que haya estudiado en profundidad.) –

+0

¿Qué quiere decir con "acceso ... a objetos"? – LavaScornedOven

+0

Esta pregunta se ha formulado anteriormente (consulte http://stackoverflow.com/questions/4029448/thread-safety-for-stl-queue y http://stackoverflow.com/questions/1362110/is-the-c-stl- stdset-thread-safe), pero todavía hay una respuesta central a esta pregunta. Dado que esta versión es tan buena como cualquiera para convertirse ** en ** el lugar central para responder esta pregunta en StackOverflow, utilice un encabezado grande para incluir el nombre de su implementación, y cite y vincule a la documentación original. –

Respuesta

5

El SGI STL

La SGI STL es la abuela de todas las otras implementaciones STL.

Ver the SGI STL docs.

La implementación SGI de STL es thread-safe sólo en el sentido de que accesos simultáneos a distintas envases son seguros, y simultánea accesos de lectura a a contenedores compartidos son seguros. Si varios subprocesos tienen acceso a un solo contenedor y al menos un subproceso puede escribir potencialmente, el usuario es responsable de garantizar la exclusión mutua entre los subprocesos durante los accesos al contenedor.

G ++

libstdc++ docs

Actualmente usamos la definición de la SGI STL de seguridad de los subprocesos.

STLport

STLPort docs

Por favor refiérase a la SGI sitio para detallado documento sobre la seguridad de los subprocesos. Basic puntos son:

  • acceso de lectura simultánea al mismo recipiente desde dentro hilos separados es seguro;
  • acceso simultáneo a contenedores distintos (no se comparte entre hilos) es seguro;
  • El usuario debe proporcionar la sincronización para todos los accesos si cualquier subproceso puede modificar el contenedor compartido .
+0

¿Alguna información sobre el recuento de referencias de cuerdas? – doron

+0

Es interesante que los documentos de STLport dicen que "el acceso simultáneo a contenedores distintos (no compartidos entre hilos) es seguro". Esta característica está deshabilitada en Android. – Ravi

2

Información general sobre el C++ estándar

El actual estándar de C++ no se ocupa de los problemas de concurrencia en absoluto, por lo que al menos por ahora no hay ningún requisito de que se aplica a todas las implementaciones.

Una respuesta significativa solo puede aplicarse realmente a una implementación específica (STLPort, en este caso). STLPort es básicamente una versión de la implementación original de SGI STL con mejoras en su portabilidad, por lo que probablemente desee comenzar con el documentation sobre seguridad de subprocesos en la versión original de SGI.

+0

La documentación del enlace anterior menciona el problema que encontré: "Alloc.h utiliza tres primitivas de bloqueo diferentes según el entorno. Además, se puede forzar a no realice ningún bloqueo definiendo _NOTHREADS ". En la distribución de Android, se definió _NOTHREADS. Cuando no lo definí, los problemas de corrupción de memoria desaparecieron. – Ravi

0

Sun WorkShop 5.0

This es un poco viejo, pero muy informativo. La conclusión es que STL solo proporciona bloqueos en los asignadores.

Sin embargo, las cadenas se consideran objetos contados, pero cualquier cambio en su recuento de referencias se realiza atómicamente. Sin embargo, esto solo es cierto cuando se pasan cadenas por valor. Dos hilos que contienen la misma referencia a un único objeto de cadena necesitarán hacer su propio bloqueo.

+0

La implementación de Linux actual tiene los bloqueos. – doron

0

Cuando utiliza p. Ej. std :: cadena u objetos similares, y cambiarlos de diferentes hilos, está compartiendo el mismo objeto entre hilos. Para realizar cualquiera de las funciones de miembro que puede invocar en el reentrada de cadena, significa que ningún otro subproceso puede afectar nuestra función de memoria, y nuestra función no puede afectar a ninguna otra llamada en otros subprocesos. La verdad es exactamente lo contrario, ya que está compartiendo el mismo objeto a través de este puntero, que se da implícitamente al llamar objetos miembro. Para ilustrar, equivalente a esta llamada

std::string a; 
a.insert(...); 

sin utilizar la sintaxis de programación orientada a objetos serían:

std::string a; 
insert(&a, ...); 

Por lo tanto, usted está violando implícitamente requisito de que ningún recurso se comparte entre las llamadas a funciones. Puede ver más here.

Espero que esto ayude.

+0

Op no comparte objeto entre subprocesos. – Basilevs

1

Por supuesto, la razón por la que no se vuelve a realizar es por el rendimiento: velocidad, menos uso de memoria, menos uso de recursos. Presumiblemente, esto se debe a que la suposición es que la mayoría de los programas cliente no serán de subprocesos múltiples.

Cuestiones relacionadas