I thread hanno un heap distinto?

Per quanto ne so, ogni thread ottiene uno stack distinto quando il thread viene creato dal sistema operativo. Mi chiedo se ogni thread ha un heap distinto anche da solo?

No. Tutti i thread condividono un heap comune.

Ogni thread ha uno stack privato , che può aggiungere e rimuovere rapidamente elementi da. Ciò rende la memoria basata sullo stack veloce, ma se si utilizza troppa memoria dello stack, come accade nella ricorsione infinita, si otterrà un overflow dello stack.

Poiché tutti i thread condividono lo stesso heap, l’accesso all’allocatore / deallocator deve essere sincronizzato. Esistono vari metodi e librerie per evitare la contesa degli allocatori .

Alcuni linguaggi consentono di creare pool privati ​​di memoria o singoli heap, che è ansible assegnare a un singolo thread.

Per impostazione predefinita, C ha un solo heap.

Detto questo, alcuni allocatori che conoscono il thread partizioneranno l’heap in modo che ogni thread abbia la propria area da cui allocare. L’idea è che questo dovrebbe migliorare l’heap.

Un esempio di tale ammasso è Hoard .

Dipende dal sistema operativo. Il runtime c standard su Windows e Unix utilizza un heap condiviso su thread. Questo significa bloccare ogni malloc / libero.

Su Symbian, ad esempio, ogni thread viene fornito con il proprio heap, sebbene i thread possano condividere i puntatori ai dati allocati in qualsiasi heap. A mio avviso, il design di Symbian è migliore in quanto non solo elimina la necessità di bloccare durante alloc / free, ma incoraggia anche le specifiche pulite della proprietà dei dati tra i thread. Anche in questo caso, quando un thread muore, prende tutti gli oggetti che gli sono stati assegnati – cioè non può perdere oggetti che ha allocato, che è una proprietà importante da avere nei dispositivi mobili con memoria vincasting.

Anche Erlang segue un progetto simile in cui un “processo” agisce come un’unità di raccolta dei rifiuti. Tutti i dati vengono comunicati tra processi mediante copia, ad eccezione dei blob binari che sono conteggiati con riferimento (credo).

Ogni thread ha il proprio stack e stack di chiamate.

Ogni thread condivide lo stesso heap.

Dipende da cosa intendi esattamente quando dici “mucchio”.

Tutti i thread condividono lo spazio degli indirizzi, quindi gli oggetti allocati su heap sono accessibili da tutti i thread. Tecnicamente, anche gli stack sono condivisi in questo senso, ovvero niente impedisce di accedere allo stack di altri thread (anche se non avrebbe quasi mai senso farlo).

D’altra parte, ci sono strutture di heap utilizzate per allocare memoria. È qui che viene eseguita tutta la contabilità per l’allocazione della memoria heap. Queste strutture sono organizzate in modo sofisticato per ridurre al minimo la contesa tra i thread, quindi alcuni thread potrebbero condividere una struttura heap (un’arena) e alcuni potrebbero utilizzare arene distinte.
Vedere il seguente thread per un’eccellente spiegazione dei dettagli: come funziona malloc in un ambiente con multithreading?

In genere, i thread condividono l’heap e altre risorse, tuttavia esistono costruzioni simili a thread che non lo fanno. Tra queste costruzioni filiformi vi sono i processi leggeri di Erlang e i processi full-on di UNIX (creati con un call to fork() ). Si potrebbe anche lavorare sulla concorrenza multi-macchina, nel qual caso le opzioni di comunicazione inter-thread sono notevolmente più limitate.

In generale, tutti i thread utilizzano lo stesso spazio di indirizzamento e pertanto di solito hanno un solo heap.

Tuttavia, può essere un po ‘più complicato. Si potrebbe cercare Thread Local Storage (TLS), ma memorizza solo valori singoli.

Specifico per Windows: lo spazio TLS può essere allocato usando TlsAlloc e liberato usando TlsFree (Panoramica qui ). Di nuovo, non è un heap, solo DWORD.

Stranamente, Windows supporta più heap per processo. Uno può memorizzare l’handle di Heap in TLS. Allora avresti qualcosa come un “Thread-Local Heap”. Tuttavia, solo l’handle non è noto agli altri thread, ma possono ancora accedere alla sua memoria utilizzando i puntatori poiché è ancora lo stesso spazio di indirizzamento.

EDIT : alcuni allocatori di memoria (in particolare jemalloc su FreeBSD) usano TLS per assegnare “arene” ai thread. Questo viene fatto per ottimizzare l’allocazione per più core riducendo l’overhead di sincronizzazione.

Sul sistema operativo FreeRTOS, le attività (thread) condividono lo stesso heap ma ognuna di esse ha il proprio stack. Questo è molto utile quando si ha a che fare con architetture a bassa potenza di RAM bassa, perché è ansible accedere / condividere lo stesso pool di memoria da più thread, ma questo ha un piccolo problema, lo sviluppatore deve tenere presente che un meccanismo per sincronizzare malloc è necessario e gratuito, ecco perché è necessario utilizzare un qualche tipo di sincronizzazione / blocco del processo quando si assegna o si libera memoria nell’heap, ad esempio un semaforo o un mutex.