Pergunta

Eu tenho uma pergunta sobre boost::shared_ptr<T>.

Há lotes de fio.

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

Se Thread_A não se importam o nowResource é o mais novo, vai esta parte do código tem problema?

eu quero dizer quando Thread_B não SetResource() completamente, Thread_A obter um ponto inteligente errado por GetResource()?

Q2

O que significa thread-safe?

Se eu não se preocupam se o recurso é mais novo, vai a shared_ptr<CResource> nowResource travar o programa quando o nowResource é liberado ou se o problema destruir o shared_ptr<CResource>?

Foi útil?

Solução

A partir do impulso :

objetos shared_ptr oferecer o mesmo nível de segurança do thread como built-in tipos. Um exemplo pode ser shared_ptr "Ler" (acessado usando apenas const operações) em simultâneo por múltiplos tópicos. diferente shared_ptr casos pode ser "escrita com" (Acedido usando operações mutáveis tal como operator= ou reset) simultaneamente por vários segmentos (Mesmo quando estas instâncias são cópias, e compartilhar a mesma contagem de referência por baixo.)

Quaisquer outros acessos simultâneos resultar em um comportamento indefinido.

Portanto, o seu uso não é seguro, uma vez que utiliza leitura e gravação de m_res simultânea. Exemplo 3 na documentação impulso também ilustra isso.

Você deve usar um separar mutex que guarda o acesso a m_res em SetResource / GetResource.

Outras dicas

ofertas boost::shared_ptr<> um certo nível de segurança do thread. A contagem de referência é manipulado de uma forma thread-safe (a menos que você configure impulso para suporte de threading desativar).

Assim, você pode copiar um shared_ptr ao redor eo Ref_Count é mantido corretamente. O que você não pode fazer com segurança em vários segmentos é modificar o próprio exemplo shared_ptr objeto real de vários segmentos (como chamar reset() sobre ele a partir de múltiplas threads). Portanto, o seu uso não é seguro - você está modificando a instância shared_ptr real em vários segmentos -. Você vai precisar de ter a sua própria proteção

No meu código, de shared_ptr são geralmente moradores ou parâmetros passados ??por valor, então não há nenhum problema. Trazê-los de um segmento para outro Eu geralmente uso uma fila thread-safe.

Claro que nada disto endereços a segurança do thread de acessar o objeto apontado pelo shared_ptr -. Que também é até você

Bem, tr1 :: shared_ptr (que se baseia na boost) documentação conta uma história diferente, o que implica que a gestão dos recursos é o segmento de seguros, ao passo que o acesso ao recurso não é.

" ...

thread-safe

C ++ 0x-únicas características são: rvalue-ref / suporte movimento, alocador de apoio, construtor aliasing, make_shared & allocate_shared. Além disso, os construtores tendo auto_ptr parâmetros são preteridos em modo C ++ 0x.

A seção Segurança de thread da documentação Impulso shared_ptr diz "objetos shared_ptr oferecer o mesmo nível de segurança do thread como tipos built-in." A implementação deve garantir que as atualizações simultâneas para casos shared_ptr separados são ainda correto quando essas instâncias compartilham uma referência contar por exemplo.

shared_ptr A (novo A); shared_ptr b (a);

// Thread 1 // Passe 2

a.reset (); b.reset ();

O objeto alocada dinamicamente deve ser destruído por exatamente um dos tópicos. referências fracas tornar as coisas ainda mais interessantes. O estado compartilhado usado para implementar shared_ptr deve ser transparente para o usuário e invariantes deve ser preservado em todos os momentos. As peças-chave do estado compartilhado são as contagens de referência fortes e fracos. Atualizações para estes necessidade de ser atômica e visível para os tópicos para garantir a limpeza correta do recurso gerenciado (que é, afinal de contas, o trabalho de shared_ptr!) Pode ser necessária a sincronização Memória sistemas multi-processador de modo que as atualizações de referência de contagem e da destruição do recurso gerenciado são livres de corrida.

... "

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

m_Res não é threadsafe, pois simultânea de leitura / gravação, Você precisa boost :: função atomic_store / carga para protege-lo.

//--- Example 3 ---
// thread A
p = p3; // reads p3, writes p
// thread B
p3.reset(); // writes p3; undefined, simultaneous read/write

Adicionar, sua classe tem uma condição referências cíclicas; o shared_ptr<CResource> m_Res não pode ser um membro de CResourceBase. Você pode usar weak_ptr vez.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top