¿Es seguro el hilo ptr compartido de boost?


Tengo una pregunta sobre boost::shared_ptr<T>.

Hay un montón de hilo.

using namespace boost;

class CResource
{
  // xxxxxx
}

class CResourceBase
{
public:
   void SetResource(shared_ptr<CResource> res)
   {
     m_Res = res;
   }

   shared_ptr<CResource> GetResource()
   {
      return m_Res;
   }
private:
   shared_ptr<CResource> m_Res;
}

CResourceBase base;

//----------------------------------------------
// Thread_A:
    while (true)
    {
       //...
       shared_ptr<CResource> nowResource = base.GetResource();
       nowResource.doSomeThing();
       //...
    }

// Thread_B:
    shared_ptr<CResource> nowResource;
    base.SetResource(nowResource);
    //...

Q1

Si Thread_A no le importa que nowResource es la más nueva, ¿tendrá problema esta parte del código?

Quiero decir cuando Thread_B no SetResource()completamente, Thread_A obtener un punto inteligente equivocado por GetResource()?

Q2

¿Qué significa thread-safe?

Si no me importa si el recurso es más reciente, el shared_ptr<CResource> nowResource bloqueará el programa cuando el nowResource se libera o el problema destruirá el shared_ptr<CResource>?

Author: Patrizio Bertoni, 2009-03-28

5 answers

De la documentación de boost :

shared_ptr los objetos ofrecen lo mismo nivel de seguridad del hilo como incorporado tipo. Una instancia shared_ptr puede ser "read" (se accede usando solo const operaciones) simultáneamente por múltiples hilo. Diferente shared_ptr las instancias se pueden " escribir en" (acceso mediante operaciones mutables como operator= o reset) simultáneamente por múltiples hilos (incluso cuando estas instancias son copias, y compartir el mismo recuento de referencia debajo.)

Cualquier otro acceso simultáneo resulta en un comportamiento indefinido.

Así que su uso no es seguro, ya que utiliza lectura y escritura simultáneas de m_res. El ejemplo 3 en la documentación de boost también ilustra esto.

Usted debe usar un mutex que protege el acceso a m_res en SetResource/GetResource.

 31
Author: sth,
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
2014-07-09 02:52:51

boost::shared_ptr<> ofrece un cierto nivel de seguridad del hilo. El recuento de referencias se manipula de una manera segura de subprocesos (a menos que configure boost para deshabilitar el soporte de subprocesos).

Así que puedes copiar un shared_ptr y el ref_count se mantiene correctamente. Lo que no puede hacer de forma segura en varios subprocesos es modificar la instancia del objeto shared_ptr real desde varios subprocesos (como llamar a reset() desde varios subprocesos). Por lo tanto, su uso no es seguro: está modificando el shared_ptr instancia en múltiples subprocesos: necesitará tener su propia protección.

En mi código, shared_ptr son generalmente locales o parámetros pasados por valor, por lo que no hay problema. Llevándolos de un hilo a otro Generalmente uso una cola segura para hilos.

Por supuesto, nada de esto aborda la seguridad del hilo de acceso al objeto señalado por el shared_ptr - eso también depende de usted.

 39
Author: Michael Burr,
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
2009-03-28 16:13:55

Bueno, la documentación tr1::shared_ptr (que se basa en boost) cuenta una historia diferente, lo que implica que la administración de recursos es segura para subprocesos, mientras que el acceso al recurso no lo es.

"...

Seguridad del hilo

Las características de C++0x-only son: rvalue-ref/move support, allocator support, aliasing constructor, make_shared & allocate_shared. Además, los constructores que toman parámetros auto_ptr están obsoletos en el modo C++0x.

La sección de Seguridad del hilo de la La documentación de Boost shared_ptr dice: "los objetos shared_ptr ofrecen el mismo nivel de seguridad de subprocesos que los tipos integrados."La implementación debe garantizar que las actualizaciones simultáneas a instancias shared_ptr separadas sean correctas incluso cuando esas instancias comparten un recuento de referencia, por ejemplo,

Shared_ptr a (new A); shared_ptr b (a);

/ / Hilo 1 / / Hilo 2

A. reset (); b. reset ();

El objeto dinámicamente asignado debe ser destruido por exactamente uno de los hilos. Débil las referencias hacen las cosas aún más interesantes. El estado compartido utilizado para implementar shared_ptr debe ser transparente para el usuario y los invariantes deben conservarse en todo momento. Las piezas clave del estado compartido son los recuentos de referencia fuertes y débiles. Las actualizaciones de estos deben ser atómicas y visibles para todos los subprocesos para garantizar la limpieza correcta del recurso administrado (¡que es, después de todo, el trabajo de shared_ptr!) En sistemas multiprocesadores puede ser necesaria la sincronización de memoria para que las actualizaciones de recuento de referencia y la destrucción de los recursos gestionados son libres de raza.

..."

Véase http://gcc.gnu.org/onlinedocs/libstdc++ / manual / memory.html#std. util.memory. shared_ptr

 3
Author: YoavT,
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
2010-12-08 13:45:43

M_Res no es threadsafe, porque es lectura/escritura simultánea, necesita la función boost::atomic_store/load para protegerlo.

//--- Example 3 ---
// thread A
p = p3; // reads p3, writes p
// thread B
p3.reset(); // writes p3; undefined, simultaneous read/write
 1
Author: xpfans,
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
2016-06-13 03:25:20

Add, su clase tiene una condición de referencias cíclicas; el shared_ptr<CResource> m_Res no puede ser un miembro de CResourceBase. Puede usar weak_ptr en su lugar.

 -1
Author: tntvampire,
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-12-20 01:50:01