Mam listę, z której chcę, aby różne wątki pobierały elementy. Aby uniknąć zablokowania muteksu strzegącego listy, gdy jest pusta, sprawdzam empty()
przed zablokowaniem.
W porządku, jeśli wezwanie do list::empty()
jest nieprawidłowe w 100% przypadków. Chcę tylko uniknąć awarii lub zakłóceń jednoczesnych list::push()
i list::pop()
połączeń.
Czy mogę bezpiecznie założyć, że VC ++ i Gnu GCC tylko czasami się empty()
mylą i nic gorszego?
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
gwarantuje stałą złożoność czasu, co w zasadzie oznacza, że rozmiar (liczba węzłów) musi być przechowywany w osobnej zmiennej; nazwijmy to size_
. std::list::empty
wtedy prawdopodobnie zwróci coś jako size_ == 0
, a jednoczesne odczytywanie i zapisywanie size_
spowoduje wyścig danych, a zatem UB.