malloc和free是執行緒安全的嗎,在多執行緒開發時用這兩個函式應該注意什麼?

時間 2021-05-06 21:26:32

1樓:

以下針對Windows:

執行緒安全

Windows上VC的malloc呼叫的是HeapAlloc

vista開始微軟把低碎片堆作為預設,效能不錯,產生的記憶體碎片也較少。

注意事項的話主要是效能方面了。我覺得優化的話分為三個粒度。

最大的粒度是從記憶體管理器級別,如google的tcmalloc,intel的tbb等,基本上也都是利用TLS來最大幅度的減少爭奪。好處是效果是全域性的,對程式設計師透明的,但不好處是需要對程式侵占式的接管malloc的呼叫(比如程式啟動時對malloc打補丁在原malloc處jump到tcmalloc自己的api),鉤住多個Windows API的呼叫,一定程度上影響穩定性,這種行為也不一定會被安全模組所允許,據我所知GPK就不允許所保護的遊戲客戶端在執行期間修改函式的跳轉位址;另外因為很多情況執行緒申請了記憶體會在另乙個執行緒釋放,記憶體管理器只能根據某種策略定期平衡這個問題,這會導致記憶體占用的增加;記憶體管理器複雜度劇增,穩定性下降。

中間的粒度是通用記憶體池,也可以利用TLS來進行優化,但如上所述不一定適合,如果用不上TLS,其實我覺得除非對實時性要求很高的程式大可不必引入普通的記憶體池,因為一方面記憶體池也是把鎖從HeapAlloc內部轉移到了記憶體池,另一方面低碎片堆內部也存在各種分配記憶體優化的資料結構(如按照不同的塊大小規模分成不同的待分配鍊錶等),也不是呼叫一次HeapAlloc就VirtualAlloc一次,做的事情跟應用層面的記憶體池相似。

最小的粒度是專用的記憶體塊/池。如果能根據業務特點,乙個會話內或乙個業務上下文內能序列的重複利用一塊或多塊記憶體的話,可以預先分配一組或若干記憶體塊來避免malloc。比如boost.

asio裡乙個連線的非同步操作需要一塊固定的記憶體用作臨時資料的儲存,提供了乙個asio_handler_allocate鉤子。而合格的asio程式設計實作中,乙個連線同時只投遞乙個讀請求或寫請求等讀到資料或寫完資料時才投遞下一次讀請求或寫請求,因此這兩個業務各自是序列的。這種情況下,只需要在連線物件建立時固定分配兩塊記憶體,各自用於讀請求和寫請求,就可避免掉asio內部對malloc的呼叫。

至於記憶體碎片的話,如果這真的成為問題,乙個是把老古董server2003扔了換新點的windows,另乙個是編譯成64位程式。至少我不覺得這是乙個問題。

2樓:楚天樂

多執行緒高併發請使用記憶體池;或者(如果可以)直接一次性分配好記憶體,後面復用。

1.malloc/free會導致系統使用者態/核心態切換,消耗大。

2.malloc/free執行緒安全意味著他要加鎖,那麼你會看到任務管理器裡cpu鋸齒形狀。

3.不斷的malloc/free執行久了會記憶體碎片。當然現在64位系統位址空間夠大,要求不是很苛刻的話問題不大

3樓:北極

目前看到的主流平台Win/*nix的主流編譯器都是執行緒安全的。

部分規模較大的嵌入式環境也是執行緒安全的。

少部分微型的嵌入式作業系統不是執行緒安全的(因為可能沒有多執行緒的概念)。

因為執行緒安全,所以malloc和free會加鎖(具體是哪種鎖就看情況了),多核的情況下會嚴重降低效率,所以不要用的太多。

多程序和多執行緒是並行還是併發?

mao.gang 我現在的理解是 按網上的並行,併發的解釋來看,概括的說,併發就是巨集觀上一起進行著的,微觀上是交替的,並行是微觀上是重疊的,還有一種說法是並行包含了併發,而多執行緒,當然,是並行的了,如果按並行包含併發來理解,如果並行概念不包含併發的話,那麼多執行緒則同時包括併發,和並行。在單cp...

畫師們做私下練習的量和時間是怎麼計畫和安排的?

同樣剛入行半年的小白,因為最開始能力弱,組長就派了大量的圖示給我,因為競爭壓力大,作為妹子也是拼了命,瘋狂畫,幾乎天天加班趕量,也曾經不斷質疑自己是不是一輩子就要幹ui了,可畢竟當初是懷著要畫出好玩的畫才進的,於是在工作沒那麼趕的是,開坑畫大圖,但是效果不盡人意,本來基礎不是很好,對整個畫面把控能力...

我是該買閃靈還是等風笛和安潔呢?

這三個幹員裡面,我最推薦的是風笛,原因是風笛不好抽,機會少。我已經沉了幾個池子了。風笛是日常使用和危機合約都可以上場的幹員。其次是安傑,我記得曾經有黃票換的機會,再推出的機會也多。屬於危機合約解題思路的高光幹員。目前看小羊和鈴蘭都可以提供一定的作用。對不起,鈴蘭我還沒有,不多評價。閃靈是最不建議換的...