Tengo un subproceso A que asigna memoria y la asigna a un puntero compartido. Luego este hilo genera otros 3 hilos X, Y y Z y pasa una copia del puntero compartido a cada uno. Cuando X, Y y Z salen de alcance, la memoria se libera. Pero existe la posibilidad de que 2 hilos X, Y salgan del alcance en el mismo momento y hay una condición de carrera en el recuento de referencias, por lo que en lugar de disminuirla en 2, solo se disminuye una vez. Por lo tanto, ahora el recuento de referencia más nuevo cae a 0, por lo que hay una pérdida de memoria. Tenga en cuenta que X, Y y Z solo leen la memoria. No escribir o restablecer el puntero compartido. Para abreviar, ¿puede haber una condición de carrera en el recuento de referencias y puede conducir a fugas de memoria?Boost Puntero compartido: acceso de lectura simultáneo a través de varios subprocesos
Respuesta
Varios otros ya han proporcionado enlaces a la documentación que explica que esto es seguro.
Para una prueba absolutamente irrefutable, vea cómo Boost Smartptr realmente implementa sus propios mutex desde cero en boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
(o el archivo correspondiente de su plataforma).
No, de acuerdo con the documentation, no pueden ocurrir estos problemas:
Diferentes
shared_ptr
casos pueden ser "escriben en" (visitada usando operaciones mutables como operador = o reajustar) simultaneosly por múltiples hilos (incluso cuando estos casos son copias, y comparten el mismo número de referencia por debajo.)
Tengo una pregunta: según la documentación, la situación mixta puede conducir a una definición indefinida beahvior: (...) // --- Ejemplo 4 --- // thread A p3 = p2; // lee p2, p3 escribe // // hilo B p2 se sale del ámbito: indefinido, el destructor se considera una "escritura" (...) no estamos en esta situación aquí? – Grimmy
El siguiente ejemplo muestra el comportamiento como 'indefinido' cuando sale del alcance. –
@Grimmy, @Brian: En mi comprensión en el ejemplo 4 de la documentación, un hilo intenta leer una variable 'shared_ptr' que vive en el otro hilo, mientras que esta variable queda fuera del alcance. Esto no estaría definido (y tampoco estaría definido para otros tipos de variables, no solo para 'shared_ptr'). Si cada hilo obtiene su propia copia de la variable 'shared_ptr', esas variables pueden usarse (y salir del alcance) de forma independiente, incluso si apuntan al mismo objeto (como en el ejemplo 2 en la documentación). – sth
boost::shared_ptr
utiliza bloqueos (o bloqueo de libre acceso atómica) para asegurar que las cuentas de referencia se actualizan atómicamente (incluso si esto no está claro desde la página de documentos). Puede configurar el uso de los bloqueos si está escribiendo código de subproceso único definiendo la macro BOOST_SP_DISABLE_THREADS
.
Tenga en cuenta que los ejemplos de documentación en http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/shared_ptr.htm#ThreadSafety que tratan problemas con varias escrituras de diferentes hilos está discutiendo esos hilos que actúan sobre los mismos shared_ptr
casos (los shared_ptr
objetos podría ser globales en los ejemplos), no diferentes shared_ptr
copias que apuntan a la mismo objeto, que es el caso de uso habitual para shared_ptr
. El ejemplo que das en la pregunta (actuando en copias que apuntan al objeto compartido) es seguro para subprocesos.
El comentario es exactamente correcto, pero también agregaría que llamar al destructor de algunos objetos desde el subproceso "incorrecto" o en el momento "incorrecto" puede crear los tipos habituales de errores de subprocesos múltiples como las razas y los interbloqueos. Si el objeto destruido solo libera memoria, esto no debería ser un problema. Sin embargo, los destructores que hacen cosas como anular el registro del objeto condenado con otras partes del sistema definitivamente pueden causar problemas. – Doug
@Doug que no tiene nada que ver con 'shared_ptr', sin embargo. Es mejor pensar en términos de acceso exclusivo bloqueado que "se bloqueó porque estaba en el lugar equivocado en el momento equivocado". Cualesquiera recursos a los que accedan los destructores deberían encerrarse. – Potatoswatter
@Potatoswatter: Sí, entiendo que el problema que planteé no tiene que ver directamente con la seguridad de subprocesos de shared_ptr. No pienso en las condiciones de carrera porque "estaba en el lugar equivocado en el momento equivocado". He encontrado errores causados por shared_ptrs que perdieron su última referencia en (digamos) un hilo no principal y donde el destructor realiza una limpieza no trivial. Sin embargo, eso es exactamente lo mismo que borrar el puntero de forma manual: "la misma seguridad de hilo que los punteros sin formato", como dice la documentación. – Doug
El documentation dice:
diferentes instancias shared_ptr pueden ser "escriben en" (visitada usando operaciones mutables como operador = o reajustar) simultaneosly por múltiples hilos (incluso cuando estos casos son copias, y comparten el el mismo recuento de referencia debajo).
De modo que si ninguno de los subprocesos accede a los objetos del puntero de los otros subprocesos, debería estar bien. Mire los ejemplos en la documentación y vea cuál es relevante en su caso.
Lo mejor que se puede hacer es actualizar a un TR1 o C++ 0x shared_ptr, a diferencia de la variedad Boost. Creo que está estandarizado que esos DEBEN ser seguros para subprocesos.
- 1. ¿El objeto Mapper de Hadoop está compartido en varios subprocesos?
- 2. acceso simultáneo a un método estático utilidad
- 3. Mapa con acceso simultáneo
- 4. Lectura de un único archivo de varios subprocesos en python
- 5. PHP y acceso simultáneo a archivos
- 6. C# lectura de varios subprocesos de colecciones no modificables
- 7. C++ acceso const estático a través de un puntero NULL
- 8. Varios subprocesos: ¿debo bloquear los datos de lectura?
- 9. Alias de puntero estricto: ¿es el acceso a través de un puntero/referencia 'volátil' una solución?
- 10. boost :: uuids :: random_generator y unicidad con varios subprocesos
- 11. Sólo lectura Diccionario - varios subprocesos llamando .ContainsKey método
- 12. Comprensión de varios subprocesos
- 13. Transacción de Entity Framework con varios subprocesos
- 14. boost :: asio, grupos de subprocesos y supervisión de subprocesos
- 15. boost :: asio, error de lectura asíncrona
- 16. ¿Acceso a múltiples subprocesos a MapPoint?
- 17. Cómo instalar boost a través de Homebrew?
- 18. Lectura de varios archivos binarios de precisión a través de fread en Matlab
- 19. Inicializar Puntero A través de la función
- 20. Asignación de memoria y desasignación a través de subprocesos
- 21. compartido AssemblyInfo de versiones uniforme a través de la solución
- 22. ¿Usarás varios subprocesos con un rendimiento de ayuda de RandomAccessFile?
- 23. puntero a un puntero
- 24. Varios archivos adjuntos a través de phpmailer
- 25. Bloquear a través de varios jvm?
- 26. Puntero NULL con boost :: shared_ptr?
- 27. demote boost :: function a un puntero de función simple
- 28. ¿Por qué no debe tener acceso a un miembro compartido/estático a través de una variable de instancia?
- 29. Consola de llamada.WriteLine de varios subprocesos
- 30. Boost :: Asio operaciones de lectura/escritura
Es interesante que dos personas usaron la misma documentación para llegar a conclusiones opuestas. –
@Mark: Yo diría que los documentos no son totalmente claros (por no decir que están equivocados, solo que son fácilmente malinterpretados). –
No entiendo por qué tienes tu pregunta.La respuesta ya está allí :) –