Diferencia entre "reentrant" y "thread-safe"

Siguiendo la línea de mis últimos posts y en respuesta a bastante gente que me ha hecho esta pregunta, voy a intentar explicar en este post la diferencia entre "reentrant" y "thread-safe" pues parece que son dos términos que crean un poco de confusión.

En muchos frameworks y librerías de desarrollo en varios lenguajes se hace referencia en la documentación de las mismas a ambos términos (a veces reentrant castellanizado como "reentrante") y parece que no queda del todo claro a que se refieren los autores cuando dicen que una clase es "reentrant", o un método es "thread-safe".

Ambos términos son utilizados para indicar como pueden las clases, métodos y funciones ser utilizados en aplicaciones que ejecutan varios hilos de ejecución en paralelo, es decir, son multihilo. Pero ambas no son lo mismo.

  • Una función (o método) thread-safe puede ser invocada por múltiples hilos de ejecución sin preocuparnos de que los datos a los que accede dicha función (o método) sean corrompidos por alguno de los hilos ya que se asegura la atomicidad de la operación, es decir, la función se ejecuta de forma serializada sin interrupciones, por lo general, adquiriendo un mutex.

  • Una función (o método) reentrant puede ser invocada desde múltiples hilos de ejecución siempre y cuando cada invocación provea sus propios datos.

Por regla general, una clase es siempre reentrant puesto que solo una instancia de la clase tiene acceso a sus datos (que debe ser privados) siempre y cuando cada hilo de ejecución ejecute su propia instancia de la clase.

Por otro lado, para que una clase o alguno de sus métodos sea thread-safe es necesario que se implemente algún mecanismo de sincronización de acceso a sus datos. Una clase o método thread-safe es siempre reentrant pero no tiene por que ser cierto al contrario.


En Genbeta Dev | Introducción al multiprocesamiento en C++
Imagen vía Intel

Portada de Genbeta