Estou lendo http://gcc.gnu.org/onlinedocs/libstdc++/manual/shared_ptr.html e alguns problemas de segurança de thread ainda não estão claros para mim:
- Padrão garante que a contagem de referência seja tratada com segurança de thread e seja independente de plataforma, certo?
- Problema semelhante - o padrão garante que apenas um encadeamento (segurando a última referência) irá chamar delete no objeto compartilhado, certo?
- shared_ptr não garante qualquer segurança de thread para objeto armazenado nele?
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));
Chamar reset () no encadeamento IV excluirá a instância anterior da classe A criada no primeiro encadeamento e a substituirá por uma nova instância? Além disso, após chamar reset () no thread IV, os outros threads verão apenas o objeto recém-criado?
c++
c++11
shared-ptr
Pateta
fonte
fonte
make_shared
vez denew
Respostas:
Como outros indicaram, você entendeu corretamente em relação às suas 3 perguntas originais.
Mas a parte final da sua edição
está incorreto. Só
d
vai apontar para o novoA(10)
, ea
,b
ec
continuará a ponto com o originalA(1)
. Isso pode ser visto claramente no exemplo a seguir.(Claramente, eu não me incomodei com nenhum threading: isso não influencia o
shared_ptr::reset()
comportamento.)A saída deste código é
fonte
Correto,
shared_ptr
use incrementos / decrementos atômicos de um valor de contagem de referência.O padrão garante que apenas um thread chamará o operador delete em um objeto compartilhado. Não tenho certeza se ele especifica especificamente que o último thread que exclui sua cópia do ponteiro compartilhado será aquele que chama delete (provavelmente, na prática, esse seria o caso).
Não, eles não fazem, o objeto armazenado nele pode ser editado simultaneamente por vários threads.
EDIT: Acompanhamento ligeiro, se você deseja ter uma idéia de como os ponteiros compartilhados funcionam em geral, você pode querer olhar a
boost::shared_ptr
fonte: http://www.boost.org/doc/libs/1_37_0/boost/shared_ptr.hpp .fonte
std::shared_ptr
não é thread-safe.Um ponteiro compartilhado é um par de dois ponteiros, um para o objeto e outro para um bloco de controle (segurando o contador ref, links para ponteiros fracos ...).
Pode haver vários std :: shared_ptr e sempre que eles acessam o bloco de controle para alterar o contador de referência é thread-safe, mas o
std::shared_ptr
próprio NÃO é thread-safe ou atômico.Se você atribuir um novo objeto a
std::shared_ptr
enquanto outro thread o usa, ele pode acabar com o novo ponteiro do objeto, mas ainda usando um ponteiro para o bloco de controle do objeto antigo => CRASH.fonte
std::shared_ptr
instância única não é thread-safe. Da referência std :: shared_ptr:If multiple threads of execution access the same shared_ptr without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur;
std::shared_ptr<T>
instância é garantida para thread-safe quando sempre usada por valor (copiado / movido) entre os limites do thread. Todos os outros usosstd::shared_ptr<T>&
não são seguros entre os limites do thread