Est malloc thread-safe?

la fonction malloc() est-elle de retour?

65
demandé sur einpoklum 2009-05-13 06:17:42

11 réponses

j'ai lu quelque part que si vous compilez avec-pthread, malloc devient thread safe. Je suis assez sûr de sa mise en œuvre dépend bien, puisque malloc est ANSI C et threads ne sont pas.

Si nous parlons de la gcc:

Compiler et lier avec -pthread et malloc() sera thread-safe, sur x86 et AMD64.

http://groups.google.com/group/comp.lang.c.moderated/browse_thread/thread/2431a99b9bdcef11/ea800579e40f7fa4

une autre opinion, plus perspicace

{malloc, calloc, realloc, free, posix_memalign} de la glibc-2.2+ filetage

http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2005-07/0323.html

38
répondu Tom 2017-05-05 01:43:12

Question: "malloc est-il rentrant?"

Réponse: non, il n'est pas. Voici une définition de ce qui rend une routine rentrant .

aucune des versions courantes de malloc ne vous permet de l'entrer de nouveau (par exemple à partir d'un gestionnaire de signal). Notez qu'une routine de rentrée peut ne pas utiliser de serrures, et presque toutes les versions de malloc existantes utilisent des serrures( ce qui les rend thread-safe), ou des variables globales / statiques (ce qui les rend thread-unsafe et non-rentrant).

Toutes les réponses jusqu'à présent de réponse "malloc est thread-safe?", qui est une question entièrement différente. À que question la réponse est cela dépend de votre bibliothèque runtime, et éventuellement des options de compilateur que vous utilisez. Sur N'importe quel UNIX moderne, vous obtiendrez un malloc sans fil par défaut. Sous Windows, utilisez /MT , /MTd , /MD ou /MDd drapeaux à obtenir bibliothèque d'exécution de thread-safe.

91
répondu Employed Russian 2018-06-10 15:16:05

Voici un extrait de malloc.c de glibc:

Thread-safety: thread-safe unless NO_THREADS is defined""

en supposant que NO_THREADS n'est pas défini par défaut, malloc est sûr au moins sur linux.

8
répondu shahkhas 2010-09-20 14:50:36

c'est une question assez ancienne et je veux apporter de la fraîcheur selon l'état actuel des choses.

Oui, actuellement malloc() est thread-safe.

De la Bibliothèque C de GNU Manuel de Référence de glibc-2.20 [released 2014-09-07] :

void * malloc (size_t size)

préliminaire: MT-Safe/...

... 1.2.2.1 concepts de sécurité POSIX:

... Les fonctions MT-Safe ou Thread-Safe sont sûres à appeler en présence d'autres threads. MT, dans MT-Safe, signifie multi Thread.

étant MT-Safe ne signifie pas qu'une fonction est atomique, ni qu'il utilise N'importe quel des mécanismes de synchronisation de mémoire POSIX expose aux utilisateurs. Il est même possible que L'appel des fonctions MT-Safe en séquence ne pas produire une combinaison MT-Safe. Par exemple, avoir un appel thread deux fonctions MT-Safe une juste après le autre ne garantit pas comportement équivalent à l'exécution atomique d'une combinaison des deux fonctions, depuis appels simultanés dans d'autres threads peuvent interférer dans un destructeurs.

optimisations de l'ensemble du programme qui pourraient fonctions en ligne à travers la bibliothèque les interfaces peuvent exposer à des réorganisations dangereuses, et donc effectuer l'interface de la bibliothèque GNU C n'est pas recommandée. La documentation de l' Le statut de sécurité MT n'est pas garanti dans le cadre de l'optimisation du programme whole. Toutefois, les fonctions définies dans les en-têtes visibles par l'utilisateur sont conçues pour: coffre-fort pour inline.

8
répondu likern 2015-10-10 13:22:41

Oui, sous POSIX.1-2008 date malloc est thread-safe.

2.9.1 Sécurité Des Fils

toutes les fonctions définies par ce volume de POSIX.1-2008 doit être sans fil, sauf que les fonctions suivantes1 ne doivent pas nécessairement être sans fil.

[une liste de fonctions qui ne contient pas malloc ]

5
répondu Tanz87 2015-04-04 01:30:01

si vous travaillez avec GLIBC, la réponse est: oui, mais.

spécifiquement, Oui, mais, s'il vous plaît, s'il vous plaît, soyez conscient que si malloc et free sont thread-safe, les fonctions de débogage ne le sont pas.

plus précisément, les fonctions extrêmement utiles mtrace(), mcheck(), et mprobe () ne sont pas thread-safe . Dans l'une des réponses les plus courtes et les plus directes que vous verrez jamais d'un projet GNU, c'est expliqué ici:

https://sourceware.org/bugzilla/show_bug.cgi?id=9939

vous devrez envisager d'autres techniques, telles que L'Électrofence, valgrind, dmalloc, etc.

donc, si vous voulez dire," sont les fonctions malloc() et free() threadsafe", la réponse est oui. Mais si vous voulez dire, "est le malloc entier / libre suite threadsafe", la réponse est non.

4
répondu breakpoint 2017-03-17 18:44:35

cela dépend de l'implémentation de la bibliothèque d'exécution C que vous utilisez. Si vous utilisez MSVC par exemple, alors il y a une option de compilateur qui vous permet de spécifier la version de la bibliothèque avec laquelle vous voulez construire (c'est-à-dire une bibliothèque de temps d'exécution qui supporte le multi-threading en étant tread-safe, ou non).

1
répondu ChrisW 2009-05-13 02:32:34

Non, il n'est pas sans fil. Il se peut qu'une fonction malloc_lock() et malloc_unlock() soit disponible dans votre bibliothèque C. Je sais que ça existe pour la bibliothèque Newlib. J'ai dû l'utiliser pour implémenter un mutex pour mon processeur, qui est multi-threadé dans le matériel.

1
répondu sybreon 2009-05-13 03:02:28

malloc et libre ne sont pas rentrants, parce qu'ils utilisent une structure de données statique qui enregistre ce que les blocs de mémoire sont libres. Par conséquent, aucune fonction de bibliothèque qui alloue ou libère de la mémoire n'est rentrante.

1
répondu user3379688 2016-10-05 07:09:10

courte réponse: oui, à partir de C11, qui est la première version de la norme C qui inclut le concept de threads, malloc et les amis sont tenus d'être thread-safe. Beaucoup de systèmes d'exploitation qui incluaient à la fois des threads et un temps D'exécution C ont fait cette Garantie bien avant la norme C, mais je ne suis pas prêt à jurer tous . Cependant, malloc et ses amis ne sont pas et n'ont jamais été tenus de rentrer.

que signifie, Il est sûr d'appeler malloc et free à partir de plusieurs threads simultanément et ne vous inquiétez pas de verrouillage, tant que vous ne violez aucune des autres règles d'allocation de mémoire (par exemple, appeler free une fois et une seule fois sur chaque pointeur retourné par malloc ). Mais il est pas sûr d'appeler ces fonctions à partir d'un gestionnaire de signal qui pourrait avoir interrompu un appel à malloc ou free dans le fil de manipulation du signal. Parfois, en utilisant des fonctionnalités au-delà de L'ISO C, vous pouvez garantir que le thread manipulant le signal n'a pas interrompu un appel à malloc ou free , par exemple avec sigprocmask et sigpause , mais essayez de ne pas le faire à moins que vous n'ayez pas d'autre option, parce qu'il est difficile d'obtenir parfaitement droite.


Longue réponse avec citation: Le C standard ajouté une notion de threads dans le 2011 "révision de la 1519260920" (lien vers le document N1570, qui est l'approximation la plus proche du texte officiel de la norme de 2011 qui est accessible au public gratuitement). Dans cette révision, section 7.1.4 paragraphe 5 stipule:

sauf indication contraire explicite dans les descriptions détaillées qui suivent, les fonctions de bibliothèque doivent empêcher les courses de données comme suit: une fonction de bibliothèque ne doit pas accéder directement ou indirectement à des objets accessibles par des threads autres que le thread courant sauf si les objets sont accessibles directement ou indirectement via les arguments de la fonction. Une fonction de bibliothèque ne doit pas modifier directement ou indirectement des objets accessibles par des threads autres que le thread courant, à moins que les objets ne soient accessibles directement ou indirectement via les arguments non-const de la fonction. Les implémentations peuvent partager leurs propres objets internes entre les threads si les objets ne sont pas visibles par les utilisateurs et sont protégés contre les courses de données.

[note de bas de page: signifie, par exemple, qu'une implémentation n'est pas autorisée à utiliser un objet statique à des fins internes sans synchronisation parce qu'elle pourrait provoquer une course de données même dans les programmes qui ne partagent pas explicitement des objets entre les threads. De même, une implémentation de memcpy n'est pas autorisée à copier des octets au-delà de la longueur spécifiée de l'objet de destination et à restaurer ensuite les valeurs originales car cela pourrait provoquer une course de données si le programme partageait ces octets entre les threads.]

si je comprends bien, c'est une façon de dire que les fonctions de bibliothèque définies par la norme C doivent être sécurisées (dans le sens habituel: vous pouvez les appeler à partir de plusieurs threads simultanément, sans vous verrouiller vous-même, à condition qu'elles ne finissent pas par se heurter sur les données passées comme arguments) à moins que la documentation pour une fonction spécifique ne le dise expressément.

puis 7.22.3p2 confirme que malloc, calloc, realloc, aligned_alloc, et free en particulier sont thread-safe:

aux fins de déterminer l'existence d'une course de données, les fonctions d'allocation de mémoire se comportent comme si elles accédaient seulement à des emplacements de mémoire accessibles par leurs arguments et non à d'autres stockages statiques de durée. Ces fonctions peuvent toutefois modifier de manière visible le stockage qu'elles attribuent ou désallocent. Un appel à libérer ou realloc que le désallocation d'une région p de mémoire synchronise avec un appel d'allocation qui affecte la totalité ou une partie de la région P. Cette synchronisation se produit après tout accès de p par la fonction de désallocation, et avant tout tel accès par la fonction d'allocation.

contraste avec ce qu'il dit sur strtok, qui n'est pas et n'a jamais été sans fil, dans 7.24.5.8p6 :

la fonction strtok n'est pas nécessaire pour éviter les courses de données avec d'autres appels à la fonction strtok.

[note: la fonction strtok_s peut être utilisée à la place pour éviter les courses de données.]

(commentaire sur la note: ne pas utiliser strtok_s , utilisez strsep .)

les anciennes versions de la norme C ne mentionnaient absolument rien à propos de la sécurité des fils. Cependant, ils did dire quelque chose au sujet de la rentrée, parce que les signaux ont toujours fait partie de la norme. Et c'est ce qu'ils ont dit, en remontant à la norme originale 1989 ANSI C (ce document a une formulation presque identique à, mais une numérotation de section très différente de, la norme ISO C qui est sorti l'année suivante):

si un signal se produit autrement qu'à la suite de l'appel de l'arrêt ou la fonction raise, le comportement n'est pas défini si le gestionnaire de signal appelle une fonction dans la bibliothèque standard autre que le signal fonction elle-même ou se réfère à tout objet avec une durée de stockage statique autre qu'en assignant une valeur à une variable de durée de stockage statique de type volatile sig_atomic_t . En outre, si un tel appel à la la fonction signal donne un retour SIG_ERR, la valeur de errno est indéterminé.

qui est une façon de dire long-winded que les fonctions de bibliothèque C sont pas requis pour être réentrant comme une règle générale. Une formulation très similaire apparaît encore dans C11, 7.14.1.1P5 :

si un signal se produit autrement qu'à la suite de l'appel de la fonction d'annulation ou de relance, le comportement n'est pas défini si le gestionnaire de signal se réfère à tout objet avec une durée de stockage statique ou de thread qui n'est pas un objet atomique libre autrement qu'en assignant une valeur à un objet déclaré comme sig_atomic_t volatile, ou si le gestionnaire de signal appelle toute fonction dans la bibliothèque standard autre que la fonction d'Annulation, la fonction _Exit, la fonction quick_exit, ou la fonction signal avec le premier argument égal au numéro de signal correspondant au signal qui a causé l'invocation du gestionnaire. De plus, si un tel appel à la fonction signal produit un retour SIG_ERR, la valeur de errno est indéterminée.

[note de bas de page: si un signal est généré par un gestionnaire de signal asynchrone, le comportement est indéterminé.]

POSIX, il faut une beaucoup plus longue, mais toujours courte par rapport à la taille globale de la bibliothèque C , la liste des fonctions en toute sécurité être appelé à partir d'un "asynchrone gestionnaire de signal", et définit également plus en détail les circonstances dans lesquelles un signal de "se produire que sur le résultat de l'appel de l'abandon ou de soulever la fonction."Si vous faites quelque chose de non trivial avec des signaux, vous écrivez probablement du code destiné à être exécuté sur un système D'exploitation avec la nature Unix (par opposition à Windows, MVS, ou quelque chose d'intégré qui n'a probablement pas une implémentation hébergée complète de C en premier lieu), et vous devriez vous familiariser avec les exigences POSIX pour eux, ainsi que les exigences ISO C.

0
répondu zwol 2018-08-13 19:38:54