Question

Supposons que j'ai un conteneur (std :: vector) de pointeurs utilisés par une application multithread. Lors de l'ajout de nouveaux pointeurs au conteneur, le code est protégé à l'aide d'une section critique (boost :: mutex). Tout va bien. Le code devrait pouvoir renvoyer l'un de ces pointeurs à un thread pour traitement, mais un autre thread distinct pourrait choisir de supprimer l'un de ces pointeurs, qui pourraient toujours être utilisés. par exemple:

thread1()
{
    foo* p = get_pointer();
    ...
    p->do_something();
}

thread2()
{
    foo* p = get_pointer();
    ...
    delete p;
}

Ainsi, thread2 pourrait supprimer le pointeur pendant que thread1 l’utilise. Nasty.

Au lieu de cela, je souhaite utiliser un conteneur de ptr partagés Boost. IIRC ces pointeurs seront comptés en tant que référence, aussi longtemps que je renverrai des ptr partagés au lieu de pointeurs bruts, en en retirant un du conteneur NE le libérera pas réellement jusqu'à ce que la dernière utilisation en sorte. c'est-à-dire

std::vector<boost::shared_ptr<foo> > my_vec;

thread1()
{
    boost::shared_ptr<foo> sp = get_ptr[0];
    ...
    sp->do_something();
}

thread2()
{
    boost::shared_ptr<foo> sp = get_ptr[0];
    ...
    my_vec.erase(my_vec.begin());
}

boost::shared_ptr<foo> get_ptr(int index)
{
    lock_my_vec();
    return my_vec[index];
}

Dans l'exemple ci-dessus, si thread1 obtient le pointeur avant l'effacement des appels de thread2, l'objet pointé sera-t-il toujours valide? Il ne sera pas réellement supprimé à la fin du thread1? Notez que l'accès au vecteur global se fera via une section critique.

Je pense que c'est ainsi que shared_ptrs fonctionne, mais je dois en être sûr.

Était-ce utile?

La solution

Pour assurer la sécurité des threads de boost :: shared_ptr, vous devez vérifier ce lien . Ce n'est pas garanti d'être sûr, mais sur de nombreuses plates-formes cela fonctionne. Modifier le std :: vector n’est pas sûr comme je l’ai dit.

Autres conseils

  

Dans l'exemple ci-dessus, si thread1 obtient le pointeur avant l'effacement des appels de thread2, l'objet pointé sera-t-il toujours valide? Il ne sera pas réellement supprimé à la fin du thread1?

Dans votre exemple, si thread1 obtient le pointeur avant thread2, alors thread2 devra attendre au début de la fonction (à cause du verrou). Donc, oui, l'objet pointé sera toujours valide. Cependant, vous voudrez peut-être vous assurer que my_vec n'est pas vide avant d'accéder à son premier élément.

Si, en outre, vous synchronisez les accès au vecteur (comme dans votre proposition de pointeur brut d'origine), votre utilisation est sécurisée. Sinon, vous risquez de tomber sous le coup de l'exemple 4 dans le lien fourni par l'autre répondant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top