У меня есть список, из которого я хочу, чтобы разные темы брали элементы. Во избежание блокировки мьютекса, защищающего список, когда он пуст, я проверяю empty()
перед блокировкой.
Это нормально, если вызов list::empty()
100% времени неправильный. Я только хочу , чтобы избежать сбоя или нарушений одновременно list::push()
и list::pop()
вызовов.
Могу ли я предположить, что VC ++ и Gnu GCC только иногда empty()
ошибаются и ничего хуже?
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
это гарантирует постоянную сложность по времени, что в основном означает, что размер (количество узлов) необходимо хранить в отдельной переменной; давайте назовем это size_
. std::list::empty
затем, вероятно, возвращает что-то как size_ == 0
, и одновременное чтение и запись size_
вызовут гонку данных, следовательно, UB.