Le typique malloc
(pour x86-64 plate-forme et système d'exploitation Linux) naïvement verrouiller un mutex au début et relâchez lorsque vous avez terminé, ou est-il verrouiller un mutex de façon plus intelligente plus fine, de niveau, de sorte que le verrouillage est réduit? Si en effet, il en fait la deuxième façon, comment fait-il cela?
Réponses
Trop de publicités?glibc 2.15
gère plusieurs d'allocation des arènes. Chaque domaine a son propre cadenas. Lorsqu'un thread a besoin d'allouer de la mémoire, malloc()
choisit une arène, qu'il se bloque, et alloue de la mémoire à partir d'elle.
Le mécanisme pour le choix d'une arène est quelque peu complexe, et vise à réduire de verrouillage:
/* arena_get() acquires an arena and locks the corresponding mutex.
First, try the one last locked successfully by this thread. (This
is the common case and handled with a macro for speed.) Then, loop
once over the circularly linked list of arenas. If no arena is
readily available, create a new one. In this latter case, `size'
is just a hint as to how much memory will be required immediately
in the new arena. */
Avec cela à l'esprit, malloc()
ressemble fondamentalement à ce (édité par souci de concision):
mstate ar_ptr;
void *victim;
arena_lookup(ar_ptr);
arena_lock(ar_ptr, bytes);
if(!ar_ptr)
return 0;
victim = _int_malloc(ar_ptr, bytes);
if(!victim) {
/* Maybe the failure is due to running out of mmapped areas. */
if(ar_ptr != &main_arena) {
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = &main_arena;
(void)mutex_lock(&ar_ptr->mutex);
victim = _int_malloc(ar_ptr, bytes);
(void)mutex_unlock(&ar_ptr->mutex);
} else {
/* ... or sbrk() has failed and there is still a chance to mmap() */
ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes);
(void)mutex_unlock(&main_arena.mutex);
if(ar_ptr) {
victim = _int_malloc(ar_ptr, bytes);
(void)mutex_unlock(&ar_ptr->mutex);
}
}
} else
(void)mutex_unlock(&ar_ptr->mutex);
return victim;
Cet allocateur est appelé ptmalloc
. Il est basé sur des travaux antérieurs par Doug Lea, et est maintenu par Wolfram Gloger.
Doug Lea malloc
utilisé grossier de verrouillage (ou pas de verrouillage, selon les paramètres de configuration), où chaque appel à l' malloc
/realloc
/free
est protégée par un mutex. C'est sûr, mais peut être inefficace dans la très multithread environnements.
ptmalloc3
, ce qui est la valeur par défaut malloc
mise en œuvre dans la bibliothèque GNU C (libc) utilisé sur la plupart des systèmes Linux ces jours-ci, a une plus fine de la stratégie, comme décrit dans aix réponse, ce qui permet à plusieurs threads simultanément allouer de la mémoire en toute sécurité.
nedmalloc
est un autre indépendant de la mise en œuvre qui revendique même mieux multithread performances qu' ptmalloc3
et divers autres allocateurs. Je ne sais pas comment cela fonctionne, et il ne semble pas du tout évident de documentation, de sorte que vous aurez à vérifier le code source pour voir comment il fonctionne.