Des threads vs re-participant
Récemment, j'ai posé une question, avec le titre de "Malloc est thread-safe?", et à l'intérieur que j'ai demandé, "Est malloc re-venu?"
J'étais sous l'impression que tous les concurrents sont thread-safe.
Cette hypothèse est fausse?
Vous devez vous connecter pour publier un commentaire.
Ré-entrant fonctions ne s'appuient pas sur des variables globales qui sont exposées dans la bibliothèque C-têtes .. prendre strtok() vs strtok_r() par exemple dans C.
Certaines fonctions ont besoin d'un endroit pour stocker un "travail en cours", ré-entrant fonctions vous permettent de spécifier ce pointeur dans le thread propre espace de stockage, non pas dans un mondial. Depuis ce stockage est exclusif à l'appel de la fonction, il peut être interrompu et re-entré (ré-entrant) et puisque dans la plupart des cas d'exclusion mutuelle au-delà de ce que la fonction met en œuvre n'est pas nécessaire pour faire ce travail, ils sont souvent considérés comme des thread-safe. Ce n'est pas, cependant, garanti par définition.
errno, cependant, est un cas un peu différent sur les systèmes POSIX (et tend à être la pièce la plus singulière dans toute explication de la façon dont tout cela fonctionne) 🙂
En bref, réentrant souvent signifie "thread-safe" (comme dans "utiliser la version réentrante de cette fonction si vous êtes à l'aide de threads"), mais "thread-safe" ne signifie pas toujours ré-entrant (ou l'inverse). Lorsque vous êtes à la recherche au fil de sécurité, simultanéité est ce que vous devez penser. Si vous avez à fournir un moyen de verrouillage et d'exclusion mutuelle pour utiliser une fonction, la fonction n'est pas intrinsèquement thread-safe.
Mais, pas toutes les fonctions doivent être examinées pour soit.
malloc()
n'a pas besoin d'être réentrant, il ne dépend pas de quoi que ce soit hors de la portée du point d'entrée pour n'importe quel thread donné (et qui est lui-même thread-safe).Les fonctions qui retournent des allouée statiquement les valeurs sont pas thread-safe, sans l'utilisation d'un mutex, futex, ou d'autres atomique mécanisme de verrouillage. Pourtant, ils n'ont pas besoin d'être réentrant si ils ne vont pas être interrompu.
c'est à dire:
Donc, comme vous pouvez le voir, le fait d'avoir plusieurs threads utilisent que sans une sorte de verrouillage serait une catastrophe .. mais il n'a pas vocation à être ré-entrant. Vous découvrirez que lorsque la mémoire allouée dynamiquement est tabou sur certaines plate-forme embarquée.
Purement fonctionnelle de la programmation, réentrant souvent n'est pas implique thread-safe, cela dépend du comportement de défini ou d'une fonction anonyme transmise à la fonction de point d'entrée, la récursivité, etc.
Une meilleure façon de mettre "thread-safe" est sécurité pour l'accès simultané , qui illustre le mieux le besoin.
TL;DR: UNE fonction peut être réentrant, thread-safe, les deux ou aucun des deux.
Les articles de Wikipédia pour fil-sécurité et la réentrance sont bien la peine de lire. Voici quelques citations:
Une fonction est thread-safe si:
Une fonction est réentrant si:
Comme des exemples de réentrance, la Wikipédia donne l'exemple d'une fonction conçue pour être appelée par le système interrompt: supposons qu'il est déjà en cours d'exécution lorsqu'un autre interruption se produit. Mais ne pensez pas que vous êtes en sécurité simplement parce que vous n'avez pas de code avec les interruptions système: vous pouvez re-ouverture de problèmes dans un seul thread programme si vous utilisez des rappels ou des fonctions récursives.
Exemples
(Légèrement modifié à partir de l'article de Wikipedia)
Exemple 1: pas thread-safe, non réentrant
Exemple 2: thread-safe, non réentrant
Exemple 3: n'est pas thread-safe, réentrant
Exemple 4: thread-safe, réentrant
t = *x
, les appelsswap()
, puist
sera remplacée, conduisant à des résultats inattendus.swap(5, 6)
d'être interrompu par uneswap(1, 2)
. Aprèst=*x
,s=t_original
ett=5
. Maintenant, après l'interruption,s=5
ett=1
. Cependant, avant la secondeswap
retourne il sera de restaurer contexte, ce qui rendt=s=5
. Maintenant, nous allons revenir à la premièreswap
avect=5 and s=t_original
et continuer aprèst=*x
. Donc, la fonction ne semble pas être ré-entrant. Rappelez-vous que chaque appel obtient sa propre copie des
alloué sur la pile.Cela dépend de la définition. Par exemple Qt utilise suivantes:
mais ils ont aussi attention: