es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Puede std::atomic_flag ser eliminado de forma segura después de llamar a notify_all?

En mi código, quiero usar un std::atomic_flag para sincronizar dos hilos. Específicamente, me gustaría usar las nuevas características wait y notify_all que se introducen en C++20.

En resumen: un hilo está esperando a que la bandera esté lista mientras que otro hilo establecerá la bandera y emitirá la notificación. Sin embargo, la complicación es que el atomic_flag vive en la pila y se destruirá después de la notificación, mientras que el primer hilo aún puede estar en la llamada a wait.

Básicamente, tengo algo equivalente al siguiente fragmento de código:

“`c++
#include <atomic>
#include <thread>

int main(int, char**)
{
auto t = std::thread{};

<pre><code>{
auto f = std::atomic_flag{};
t = std::thread{[&f] { f.wait(false); }};

// Asegura que 't' está esperando en 'f' (no es una garantía del 100%, pero se entiende el punto)
std::this_thread::sleep_for(std::chrono::milliseconds{50});

f.test_and_set();
f.notify_all();
} // <— 'f' se destruye aquí pero 't' podría seguir en la llamada a wait

t.join();
return 0;
</code></pre>

}
“`

En el pasado, he utilizado boost::latch para situaciones como esta y sé por experiencia que este patrón casi siempre causará un cierre inesperado o una aserción. Sin embargo, reemplazar boost::latch con std::atomic_flag no ha resultado en ningún cierre inesperado, aserción o bloqueo.

Mi pregunta es: ¿es seguro destruir un std::atomic_flag después de llamar a notify_all (es decir, con hilos despertados potencialmente aún en el método wait)?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    No, no es seguro destruir un std::atomic_flag después de una llamada a notify_all, ya que podría haber hilos esperando en la bandera en el momento de la destrucción. El comportamiento en esta situación es indefinido y puede resultar en fallos, bloqueos u otros problemas. Se recomienda utilizar un primitivo de sincronización diferente, como std::condition_variable, que permita una señalización segura entre hilos.

Comments are closed.