std:: explicación de la seguridad del hilo del RPP compartido


Estoy leyendo http://gcc.gnu.org/onlinedocs/libstdc++/manual/shared_ptr.html y algunos problemas de seguridad del hilo todavía no están claros para mí:

  1. El estándar garantiza que el conteo de referencia es seguro para el hilo y es independiente de la plataforma, ¿verdad?
  2. Problema similar: el estándar garantiza que solo un subproceso (manteniendo la última referencia) llamará a delete en el objeto compartido, ¿verdad?
  3. shared_ptr no garantiza ninguna seguridad de hilo para el objeto almacenado en ¿eso?

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

Llamar a reset() en thread IV eliminará la instancia anterior de una clase creada en el primer thread y la reemplazará con una nueva instancia? Además, después de llamar a reset () en el subproceso IV, otros subprocesos verán solo el objeto recién creado?

Author: lysergic-acid, 2012-02-03

3 answers

Como otros han señalado, lo has resuelto correctamente con respecto a tus 3 preguntas originales.

Pero la parte final de su edición

Llamar a reset() en thread IV eliminará la instancia anterior de una clase creada en el primer thread y la reemplazará con una nueva instancia? Además, después de llamar a reset () en el subproceso IV, otros subprocesos verán solo el objeto recién creado?

Es incorrecto. Solo d apuntará al nuevo A(10), y a, b, y c será continúe señalando el original 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 enhebrado: eso no tiene en cuenta el comportamiento shared_ptr::reset().)

La salida de este código es

A: 1 b: 1 c: 1 d: 1

A: 1 b: 1 c: 1 d: 10

 76
Author: Nicu Stiurca,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-30 05:35:04
  1. Correct, shared_ptr s use incrementos/decrementos atómicos de un valor de recuento de referencia.

  2. El estándar garantiza que solo un subproceso llamará al operador delete en un objeto compartido. No estoy seguro de si especifica específicamente el último hilo que elimina su copia del puntero compartido será el que llama a eliminar (probablemente en la práctica este sería el caso).

  3. No lo hacen, el objeto almacenado en él puede ser editado simultáneamente por múltiples hilos.

EDITAR: Ligero seguimiento, si desea tener una idea de cómo funcionan los punteros compartidos en general, es posible que desee mirar la fuente boost::shared_ptr: http://www.boost.org/doc/libs/1_37_0/boost/shared_ptr.hpp .

 31
Author: NothingMore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-18 13:11:56

Std::shared_ptr no es seguro para subprocesos.

Un puntero compartido es un par de dos punteros, uno al objeto y otro a un bloque de control (sosteniendo el contador ref, enlaces a punteros débiles ...).

Puede haber múltiples std::shared_pointer y cada vez que acceden al bloque de control para cambiar el contador de referencia es threadsafe pero el "std::shared_ptr" en sí NO es threadsafe o atomic.

Si asigna un nuevo objeto a un std:: shared_pointer mientras otro hilo lo usa, podría terminar con el nuevo puntero de objeto, pero aún usando un puntero al bloque de control del antiguo objeto = > CRASH.

 10
Author: Lothar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-15 19:15:13