Вопрос по linux, gcc, c, x86-64 – Как работает malloc в многопоточной среде?

47

Типичныйmalloc (для платформы x86-64 и ОС Linux) наивно блокирует мьютекс в начале и освобождает его по завершении, или он блокирует мьютекс более умным способом на более тонком уровне, так что конфликт блокировок уменьшается? Если он действительно делает это вторым способом, как он это делает?

В каком контексте вы это видели? Какой-либо цитируемый код или ссылка? Raulp
Я должен сказать, что есть лучшие альтернативы malloc при использовании многопоточной среды, используйте google std''OrgnlDave
мягко: я спрашиваю, не говоря. pythonic

Ваш Ответ

2   ответа
20

Doug Lea'smalloc используется грубая блокировка (или без блокировки, в зависимости от настроек конфигурации), где каждый вызовmalloc/realloc/free защищен глобальным мьютексом. Это безопасно, но может быть неэффективно в многопоточных средах.

ptmalloc3, который является значением по умолчаниюmallocеализация @ в библиотеке GNU C (libc), используемой в настоящее время на большинстве систем Linux, имеет более детальную стратегию, как описано в ответ Экс, что позволяет нескольким потокам одновременно безопасно распределять память.

nedmalloc - это еще одна независимая реализация, которая претендует на лучшую многопотоковую производительность, чемptmalloc3 и различные другие распределители. Я не знаю, как это работает, и нет очевидной документации, поэтому вам нужно проверить исходный код, чтобы увидеть, как он работает.

Я до сих пор не знаю, является ли nedmalloc настоящим инженерным подвигом или SEO-спамом ...: -) R..
Также tcmalloc от Google, который использует блокировки на ведра размером по вашему запросу. Лучшая производительность потока с меньшим количеством конфликтов и большим распределением излишков. evil otto
@ R ..: На первый взгляд это выглядит немного подозрительно, но у него есть исходный код, так что вы можете сами сравнить его (я этого не делал). Даг Ли также говорит: «Если вы используете malloc в параллельной программе, рассмотрите вместо этого использование nedmalloc или ptmalloc» в комментариях кdlmalloc.c. Поэтому я думаю, что это законно. Adam Rosenfield
37

glibc 2.15 управляет множественным распределением Арен. Каждая арена имеет свой собственный замок. Когда поток должен выделить память,malloc() выбирает арену, блокирует ее и выделяет из нее память.

Механизм выбора арены несколько продуман и нацелен на снижение конкуренции за блокировку:

/* 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() в основном выглядит так (отредактировано для краткости):

  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. Он основан на предыдущая работа от Doug Lea и поддерживается Wolfram Gloger.

Похожие вопросы