c++ - smart - unique pointer
std:: shared_ptr thread safety explain (3)
Estoy leyendo http://gcc.gnu.org/onlinedocs/libstdc++/manual/shared_ptr.html y algunos problemas de seguridad de subprocesos aún no están claros para mí:
- Standard garantiza que el recuento de referencias se maneja con seguridad de subprocesos y es independiente de la plataforma, ¿verdad?
- Problema similar: garantías estándar de que solo un hilo (que contiene la última referencia) llamará a eliminar en el objeto compartido, ¿verdad?
- shared_ptr no garantiza ningún hilo de seguridad para el objeto almacenado en él?
EDITAR:
Pseudo código:
// Thread I
shared_ptr<A> a (new A (1));
// Thread II
shared_ptr<A> b (a);
// Thread III
shared_ptr<A> c (a);
// Thread IV
shared_ptr<A> d (a);
d.reset (new A (10));
¿El reinicio de llamada () en el hilo IV eliminará la instancia previa de la clase A creada en el primer hilo y la reemplazará con una nueva instancia? Además, después de llamar a reset () en el hilo IV, ¿otros hilos verán solo el objeto recién creado?
Correcto,
shared_ptr
s usa incrementos / decrementos atómicos de un valor de recuento de referencia.El estándar garantiza que solo un hilo llamará al operador de eliminación en un objeto compartido. No estoy seguro si especifica específicamente que el último hilo que borre su copia del puntero compartido será el que llama eliminar (probablemente en la práctica sería el caso).
No, no es así, el objeto almacenado en él puede ser editado simultáneamente por múltiples hilos.
EDITAR: Seguimiento leve, si desea tener una idea de cómo funcionan los punteros compartidos en general, es posible que desee consultar la fuente boost::shared_ptr
: http://www.boost.org/doc/libs/1_37_0/boost/shared_ptr.hpp .
Como han señalado otros, lo has descifrado correctamente con respecto a tus 3 preguntas originales.
Pero la parte final de tu edición
¿El reinicio de llamada () en el hilo IV eliminará la instancia previa de la clase A creada en el primer hilo y la reemplazará con una nueva instancia? Además, después de llamar a reset () en el hilo IV, ¿otros hilos verán solo el objeto recién creado?
Es incorrecto. Solo d
apuntará a la nueva A(10)
, y a
, b
y c
continuarán apuntando a la A(1)
. Esto se puede ver claramente en el siguiente breve ejemplo.
#include <memory>
#include <iostream>
using namespace std;
struct A
{
int a;
A(int a) : a(a) {}
};
int main(int argc, char **argv)
{
shared_ptr<A> a(new A(1));
shared_ptr<A> b(a), c(a), d(a);
cout << "a: " << a->a << "/tb: " << b->a
<< "/tc: " << c->a << "/td: " << d->a << endl;
d.reset(new A(10));
cout << "a: " << a->a << "/tb: " << b->a
<< "/tc: " << c->a << "/td: " << d->a << endl;
return 0;
}
(Claramente, no me molesté con ningún subproceso: eso no tiene en cuenta el shared_ptr::reset()
.)
El resultado de este código es
a: 1 b: 1 c: 1 d: 1
a: 1 b: 1 c: 1 d: 10
std :: shared_ptr no es seguro para subprocesos.
Un puntero compartido es un par de dos punteros, uno para el objeto y otro para un bloque de control (que contiene el contador de referencia, enlaces a punteros débiles ...).
Puede haber varios std :: shared_pointer y cada vez que acceden al bloque de control para cambiar el contador de referencia, es seguro para la ejecución de los hilos, pero el "std :: shared_ptr" en sí no es threadsafe o atomic.
Si asigna un nuevo objeto a std :: shared_pointer mientras otro hilo lo usa, puede terminar con el nuevo puntero a objeto pero aún usando un puntero al bloque de control del antiguo objeto => CRASH.