Tengo una lista de la que quiero diferentes hilos para tomar elementos. Para evitar bloquear el mutex que protege la lista cuando está vacío, verifico empty()
antes de bloquear.
Está bien si la llamada a list::empty()
no es correcta el 100% del tiempo. Solo quiero evitar fallar o interrumpir concurrentes list::push()
y list::pop()
llamadas.
¿Estoy seguro de asumir que VC ++ y Gnu GCC solo a veces se empty()
equivocan y nada peor?
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
ha garantizado una complejidad de tiempo constante, lo que básicamente significa que el tamaño (número de nodos) debe almacenarse en una variable separada; Digamos que es size_
. std::list::empty
entonces es probable que devuelva algo como size_ == 0
, y la lectura y escritura concurrentes size_
causarían una carrera de datos, por lo tanto, UB.