マルチスレッド環境で malloc はどのように動作しますか? 質問する

マルチスレッド環境で malloc はどのように動作しますか? 質問する

典型的なmalloc(x86-64 プラットフォームおよび Linux OS の場合) は、最初に単純にミューテックスをロックし、完了したら解放しますか、それとも、同時呼び出しのロック競合が軽減されるように、より巧妙な方法でより細かいレベルでミューテックスをロックしますか? 実際に 2 番目の方法で行う場合、どのように行うのですか?

ベストアンサー1

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 によって保守されています。

おすすめ記事