如何在多线程环境中的malloc工作? [英] How does malloc work in a multithreaded environment?

查看:166
本文介绍了如何在多线程环境中的malloc工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请问典型的malloc (用于x86-64的平台和Linux操作系统)开头天真地锁定一个互斥体,完成后释放它,还是它锁定一个互斥体在更精细的水平更聪明的方式,使锁争用减少?如果它确实做它的第二种方式,它是如何做到的?

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 clever way at a finer level, so that lock contention is reduced? If it indeed does it the second way, how does it do it?

推荐答案

的glibc 2.15 运行多个分配的阿里纳斯的。每个赛场都有自己的锁。当一个线程需要分配内存,的malloc()挑选一个舞台上,将其锁定,并从中分配内存。

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

考虑到这一点,的malloc()基本上看起来像这样(编辑为简洁起见):

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;

这分配器被称为 ptmalloc 。它是基于早期工作,由钨格洛格尔维护。

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

这篇关于如何在多线程环境中的malloc工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆