J'ai une liste dont je veux que différents threads récupèrent des éléments. Afin d'éviter de verrouiller le mutex gardant la liste lorsqu'elle est vide, je vérifie empty()
avant de verrouiller.
Ce n'est pas grave si l'appel list::empty()
n'est pas correct dans 100% des cas. Je veux seulement éviter de planter ou de perturber les appels list::push()
et les list::pop()
appels simultanés .
Suis-je sûr de supposer que VC ++ et Gnu GCC ne se tromperont que parfois empty()
et rien de pire?
if(list.empty() == false){ // unprotected by mutex, okay if incorrect sometimes
mutex.lock();
if(list.empty() == false){ // check again while locked to be certain
element = list.back();
list.pop_back();
}
mutex.unlock();
}
std::list::size
a garanti une complexité temporelle constante, ce qui signifie essentiellement que la taille (nombre de nœuds) doit être stockée dans une variable distincte; appelons cela size_
. std::list::empty
puis renvoie probablement quelque chose comme size_ == 0
, et la lecture et l'écriture simultanées size_
provoqueraient la course aux données, donc UB.