Soweit ich weiß, erhält jeder Thread einen eigenen Stapel, wenn der Thread vom Betriebssystem erstellt wird. Ich frage mich, ob jeder Thread auch einen eigenen Heap hat.
Soweit ich weiß, erhält jeder Thread einen eigenen Stapel, wenn der Thread vom Betriebssystem erstellt wird. Ich frage mich, ob jeder Thread auch einen eigenen Heap hat.
Antworten:
Nein. Alle Threads haben einen gemeinsamen Heap.
Jeder Thread verfügt über einen privaten Stapel , über den Elemente schnell hinzugefügt und entfernt werden können. Dies macht den stapelbasierten Speicher schnell, aber wenn Sie zu viel Stapelspeicher verwenden, wie dies bei unendlicher Rekursion der Fall ist, kommt es zu einem Stapelüberlauf.
Da alle Threads denselben Heap verwenden, muss der Zugriff auf den Allokator / Deallocator synchronisiert werden. Es gibt verschiedene Methoden und Bibliotheken, um Allokatorkonflikte zu vermeiden .
In einigen Sprachen können Sie private Speicherpools oder einzelne Heaps erstellen, die Sie einem einzelnen Thread zuweisen können.
you will get a stack overflow.
Ein Stapelüberlauf bei Stapelüberlauf!
Standardmäßig hat C nur einen einzigen Heap.
Das heißt, einige Allokatoren, die Thread-fähig sind, partitionieren den Heap so, dass jeder Thread seinen eigenen Bereich zum Zuweisen hat. Die Idee ist, dass dies die Heap-Skala verbessern sollte.
Ein Beispiel für eine solche Haufen ist Hoard .
Hängt vom Betriebssystem ab. Die Standard-c-Laufzeit unter Windows und Unices verwendet einen gemeinsam genutzten Heap über Threads hinweg. Dies bedeutet, dass jeder Malloc / Free gesperrt wird.
Unter Symbian verfügt beispielsweise jeder Thread über einen eigenen Heap, obwohl Threads Zeiger auf Daten gemeinsam nutzen können, die in einem beliebigen Heap zugewiesen sind. Das Design von Symbian ist meiner Meinung nach besser, da es nicht nur das Sperren während der Zuweisung / Freigabe überflüssig macht, sondern auch eine saubere Angabe des Datenbesitzes zwischen Threads fördert. Auch in diesem Fall nimmt ein Thread, wenn er stirbt, alle ihm zugewiesenen Objekte mit, dh er kann keine zugewiesenen Objekte verlieren, was eine wichtige Eigenschaft bei Mobilgeräten mit eingeschränktem Speicher ist.
Erlang folgt auch einem ähnlichen Design, bei dem ein "Prozess" als Einheit der Speicherbereinigung fungiert. Alle Daten werden zwischen Prozessen durch Kopieren übertragen, mit Ausnahme von binären Blobs, die als Referenz gezählt werden (glaube ich).
Es hängt davon ab, was Sie genau meinen, wenn Sie "Haufen" sagen.
Alle Threads teilen sich den Adressraum, sodass auf Heap-zugewiesene Objekte von allen Threads aus zugegriffen werden kann. Technisch gesehen werden Stapel auch in diesem Sinne gemeinsam genutzt, dh nichts hindert Sie daran, auf den Stapel anderer Threads zuzugreifen (obwohl dies fast nie sinnvoll wäre).
Andererseits gibt es Heap- Strukturen, die zum Zuweisen von Speicher verwendet werden. Hier erfolgt die gesamte Buchhaltung für die Zuordnung des Heapspeichers. Diese Strukturen sind ausgefeilt organisiert, um Konflikte zwischen den Threads zu minimieren. Einige Threads teilen sich möglicherweise eine Heap-Struktur (eine Arena), andere verwenden möglicherweise unterschiedliche Arenen.
Im folgenden Thread finden Sie eine hervorragende Erklärung der Details: Wie funktioniert malloc in einer Multithread-Umgebung?
In der Regel teilen sich Threads den Heap und andere Ressourcen, es gibt jedoch threadähnliche Konstruktionen, die dies nicht tun. Zu diesen threadähnlichen Konstruktionen gehören Erlangs Lightweight-Prozesse und UNIXs Full-On-Prozesse (erstellt mit einem Aufruf von fork()
). Möglicherweise arbeiten Sie auch an der Parallelität mehrerer Computer. In diesem Fall sind Ihre Kommunikationsoptionen zwischen Threads erheblich eingeschränkter.
Im Allgemeinen verwenden alle Threads denselben Adressraum und haben daher normalerweise nur einen Heap.
Es kann jedoch etwas komplizierter sein. Möglicherweise suchen Sie nach TLS ( Thread Local Storage ), es werden jedoch nur einzelne Werte gespeichert.
Windows-spezifische: TLS-Raum kann mit zugewiesen TlsAlloc und befreit mit TlsFree (Übersicht hier ). Auch hier ist es kein Haufen, nur DWORDs.
Seltsamerweise unterstützt Windows mehrere Heaps pro Prozess. Man kann das Handle des Heaps in TLS speichern. Dann hätten Sie so etwas wie einen "Thread-Local Heap". Nur das Handle ist den anderen Threads nicht bekannt. Sie können dennoch mithilfe von Zeigern auf den Speicher zugreifen, da es sich immer noch um denselben Adressraum handelt.
BEARBEITEN : Einige Speicherzuweiser (insbesondere jemalloc unter FreeBSD) verwenden TLS, um Threads "Arenen" zuzuweisen. Dies wird durchgeführt, um die Zuordnung für mehrere Kerne zu optimieren, indem der Synchronisationsaufwand verringert wird.
Unter dem FreeRTOS-Betriebssystem teilen sich Aufgaben (Threads) denselben Heap, aber jeder von ihnen hat seinen eigenen Stapel. Dies ist sehr praktisch, wenn es um Architekturen mit geringem Stromverbrauch und geringem Arbeitsspeicher geht, da mehrere Threads auf denselben Speicherpool zugreifen / ihn gemeinsam nutzen können. Dies ist jedoch mit einem kleinen Haken verbunden. Der Entwickler muss berücksichtigen, dass ein Mechanismus zum Synchronisieren von Malloc vorhanden ist und frei ist erforderlich, deshalb ist es notwendig, eine Art Prozesssynchronisation / -sperre zu verwenden, wenn Speicher auf dem Heap zugewiesen oder freigegeben wird, beispielsweise ein Semaphor oder ein Mutex.