How does malloc work in a multithreaded environment?

前端 未结 2 1859
清歌不尽
清歌不尽 2020-12-04 11:52

Does the typical malloc (for x86-64 platform and Linux OS) naively lock a mutex at the beginning and release it when done, or does it lock a mutex in a more cle

2条回答
  •  猫巷女王i
    2020-12-04 12:35

    glibc 2.15 operates multiple allocation arenas. Each arena has its own lock. When a thread needs to allocate memory, malloc() picks an arena, locks it, and allocates memory from it.

    The mechanism for choosing an arena is somewhat elaborate and is aimed at reducing lock contention:

    /* 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. */
    

    With this in mind, malloc() basically looks like this (edited for brevity):

      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;
    

    This allocator is called ptmalloc. It is based on earlier work by Doug Lea, and is maintained by Wolfram Gloger.

提交回复
热议问题