Ich habe eine Liste, aus der verschiedene Threads Elemente abrufen sollen. Um zu vermeiden, dass der Mutex die Liste schützt, wenn er leer ist, überprüfe ich dies empty()
vor dem Sperren.
Es ist in Ordnung, wenn der Anruf zu list::empty()
100% nicht richtig ist. Ich möchte nur vermeiden, dass gleichzeitig list::push()
und bei list::pop()
Anrufen abgestürzt oder gestört wird .
Kann ich davon ausgehen, dass VC ++ und Gnu GCC nur manchmal empty()
falsch liegen und nichts Schlimmeres?
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
eine konstante zeitliche Komplexität garantiert hat, was im Grunde bedeutet, dass die Größe (Anzahl der Knoten) in einer separaten Variablen gespeichert werden muss. Nennen wir es size_
. std::list::empty
dann wird wahrscheinlich etwas zurückgegeben als size_ == 0
, und das gleichzeitige Lesen und Schreiben von size_
würde Datenrennen verursachen, daher UB.