[英]How does malloc work in a multithreaded environment?
典型的malloc
(對於 x86-64 平台和 Linux 操作系統)是天真地在開始時鎖定互斥量並在完成時釋放它,還是以更聰明的方式在更精細的級別鎖定互斥量,從而減少鎖爭用並發調用? 如果確實是第二種方式,它是如何做到的?
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;
Doug Lea的malloc
使用了粗鎖(或者沒有鎖定,具體取決於配置設置),每次調用malloc
/ realloc
/ free
都受全局互斥鎖的保護。 這是安全的,但在高度多線程環境中可能效率低下。
ptmalloc3
是目前大多數Linux系統上使用的GNU C庫(libc)中的默認malloc
實現,它具有更細粒度的策略,如aix的答案中所述 ,它允許多個線程同時安全地分配內存。
nedmalloc
是另一個獨立的實現,它聲稱比ptmalloc3
和其他各種分配器具有更好的多線程性能。 我不知道它是如何工作的,似乎沒有任何明顯的文檔,所以你必須檢查源代碼,看看它是如何工作的。
除了@NPE提到的ptmalloc
,還有Google提供的tcmalloc
,在某些場景下,經測試運行速度略快於ptmalloc
(例如:執行10^6次malloc()
並釋放時) ).
它使用全局堆和每線程堆,以便每個線程都可以使用全局堆。 全局堆上只有互斥鎖,每線程堆上沒有。 對於每個單獨的線程,他們可以從全局堆中提取存儲並釋放該存儲,以便該存儲進入每個線程堆。
每個線程堆都由單獨的線程擁有。 除非情況不平衡,否則線程會將存儲移回全局堆。
代碼實現在這里: https://github.com/google/tcmalloc
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.