Les fonctions réentrantes ne s'appuient pas sur les variables globales qui sont exposées dans les en-têtes de la bibliothèque C prenez par exemple strtok() contre strtok_r() en C.
Certaines fonctions ont besoin d'un endroit pour stocker un "travail en cours", les fonctions réentrantes vous permettent de spécifier ce pointeur dans le propre stockage du thread, et non dans un global. Étant donné que ce stockage est exclusif à la fonction appelante, il peut être interrompu et les fonctions ré-entrantes peuvent être utilisées. rentré sur (ré-entrants) et puisque dans la plupart des cas, l'exclusion mutuelle au-delà de ce que la fonction implémente n'est pas nécessaire pour que cela fonctionne, ils sont souvent considérés comme étant sans fil . Ce n'est cependant pas garanti par définition.
errno, cependant, est un cas légèrement différent sur les systèmes POSIX (et tend à être l'excentrique dans toute explication de la façon dont tout cela fonctionne) :)
En bref, le réentrant souvent signifie thread safe (comme dans "utilisez la version réentrante de cette fonction si vous utilisez des threads"), mais thread safe ne signifie pas toujours re-entrant (ou l'inverse). Quand vous regardez la thread-safety, Concurrence est ce à quoi vous devez penser. Si vous devez fournir un moyen de verrouillage et d'exclusion mutuelle pour utiliser une fonction, alors la fonction n'est pas intrinsèquement sûre pour les threads.
Mais il n'est pas nécessaire d'examiner toutes les fonctions pour l'une ou l'autre. malloc()
n'a pas besoin d'être réentrant, il ne dépend de rien en dehors de la portée du point d'entrée d'un thread donné (et est lui-même thread safe).
Les fonctions qui renvoient des valeurs allouées statiquement sont no thread safe sans l'utilisation d'un mutex, futex, ou autre mécanisme de verrouillage atomique. Pourtant, ils n'ont pas besoin d'être réentrants s'ils ne sont pas interrompus.
c'est-à-dire :
static char *foo(unsigned int flags)
{
static char ret[2] = { 0 };
if (flags & FOO_BAR)
ret[0] = 'c';
else if (flags & BAR_FOO)
ret[0] = 'd';
else
ret[0] = 'e';
ret[1] = 'A';
return ret;
}
Donc, comme vous pouvez le voir, l'utilisation de ce système par plusieurs threads sans une sorte de verrouillage serait un désastre mais il n'a aucun intérêt à être ré-entrant. Vous rencontrerez ce problème lorsque la mémoire allouée dynamiquement sera taboue sur une plateforme embarquée.
Dans la programmation purement fonctionnelle, le réentraînement est souvent n'a pas Implicitement thread safe, cela dépendrait du comportement des fonctions définies ou anonymes passées au point d'entrée de la fonction, de la récursion, etc.
Une meilleure façon d'exprimer la notion de "thread safe" est la suivante sûr pour l'accès simultané qui illustre mieux le besoin.