Supposons que je dispose d'une collection thread-safe de choses (appelons-la ThingList), et je souhaite ajouter la fonction suivante.Renvoyer des pointeurs de manière sûre pour les threads
Thing * ThingList::findByName(string name)
{
return &item[name]; // or something similar..
}
Mais en faisant cela, je l'ai confié la responsabilité de la sécurité des threads au code d'appel, qui devrait faire quelque chose comme ceci:
try
{
list.lock(); // NEEDED FOR THREAD SAFETY
Thing *foo = list.findByName("wibble");
foo->Bar = 123;
list.unlock();
}
catch (...)
{
list.unlock();
throw;
}
Il est évident qu'un verrou RAII/déverrouiller l'objet serait simplifier/supprimer le try/catch/unlock, mais il est toujours facile pour l'appelant d'oublier.
Il y a quelques alternatives que j'ai regardé:
- Thing Retour en valeur, au lieu d'un pointeur - bien à moins que vous devez modifier la chose
- Ajouter la fonction
ThingList::setItemBar(string name, int value)
- fin, mais ils tendent à proliférer - Renvoyer un objet pointeur qui verrouille la liste à la création et la déverrouille à nouveau en cas de destruction. Vous ne savez pas si c'est une bonne ou une mauvaise pratique ...
Quelle est la bonne approche pour y faire face?
La « Merge » est agréable, mais il y a une hypothèse cachée que les objets Thing savent comment se localiser dans la liste. Vous pouvez également passer la "clé" pour fusionner, mais vous avez alors le problème de fusionner un élément qui a été supprimé ... – Roddy