Während ich eine Antwort darüber las, was alles die Threads teilen, stolperte ich über den Begriff "call stack" .Während ich mir der Tatsache bewusst bin, dass Threads ihren eigenen Stack haben, den sie nicht mit anderen Threads teilen, verstehe ich nicht was Call Stack würde in Bezug auf einen Thread bedeuten. Ich habe einige Antworten gesehen, aber sie waren nicht sehr klar. Bitte erläutern Sie, was ein Call-Stack bedeutet und wie sich dieser im Kontext von Multitasking vom Stack unterscheidet. GrüßeUnterschied zwischen einem Stack und Call-Stack in Multithreading?
Antwort
Bitte erläutern Sie, was ein Call-Stack bedeutet und wie es sich vom Stack im Zusammenhang mit Multitasking unterscheidet.
Die Unterscheidung ist subtil, aber auf diese Weise habe ich es verstanden. Oft benutzen Leute diese etwas austauschbar, aber ein Call-Stack ist nur eine Datenstruktur. Es beschreibt einen Stapel von Funktionsaufrufen zusammen mit verschiedenen assoziierten Zustand wie die Werte der lokalen Variablen, Rückkehrzustände, etc.
Der Stapel ist auch eine Datenstruktur, aber es ist letztlich ein Speicherzuordner. Er fasst Speicher zusammen, der für einen Thread reserviert ist, der für Dinge wie den Aufruf-Stapel mit einer sehr einfachen, konstanten Zeit, symmetrischen push
und pop
Art des Zuweisens und Freigebens von Speicher verwendet wird.
Sie könnten es wie die Beziehung zwischen std::vector
und std::allocator
grob gesagt denken. std::vector
ist streng genommen eine Datenstruktur. std::allocator
reserviert Speicher dafür (was normalerweise eine Datenstruktur hinter der Haube beinhaltet, aber eine Datenstruktur, die nur für die Speicherverwaltung verwendet wird). Aber std::vector
muss nicht unbedingt std::allocator
verwenden.
Konzeptionell muss eine Aufrufliste den Stapel nicht tatsächlich verwenden, um Speicher zuzuordnen. Es wäre schwierig, in der Praxis einen Compiler zu finden, der dies jemals tut. Zum Beispiel könnte ein Aufruf-Stack tatsächlich den Heap anstelle des Stacks verwenden. Es könnte tatsächlich jedes Mal eine Speicherzuweisung für die lineare Zeit erfordern, wenn es nur ein Argument für einen Funktionsaufruf drücken möchte. Das wäre schrecklich, aber es ist nicht unvereinbar mit dem Konzept eines Call-Stacks. Normalerweise verwenden Aufrufstapel den Thread-lokalen Stapel, um Speicher zuzuordnen, da dies praktisch und effizient ist, der LIFO-Art der erwarteten Zuweisungen/Freigabe entspricht und jedem Thread eigenen Speicherplatz zuweist (Engpässe im Zusammenhang mit dem Zugriff auf gemeinsam genutzten Speicher)).
Lesen Sie wikipages über call stack und multithreading.
In der Theorie könnte eine C-Implementierung nicht einmal einen Stack verwenden. In der Praxis werden alle kompilierte C-Implementierung, die ich gehört habe, einen Call-Stack verwenden, der der Prozessor-Stack ist (einige Prozessoren, wahrscheinlich Itanium IA-64, haben zwei Maschinenstapel), wenn es einen gibt (AFAIK, der IBM z Series Mainframe don ') t haben Hardware Stapel, es ist eine konventionelle Verwendung einiger Register). Also für die meisten Prozessoren & ABI s (ARM, x86, x86-64, ...) der Aufruf Stapel ist der Stapel und jeder Thread hat seine eigene.
IBM Mainframes haben tatsächlich einen wunderbaren Hardware-Stack, der normalerweise als Linkage Stack bezeichnet wird. Ein Programmierer hat die Wahl, seinen eigenen Stack zu verwalten (der schneller sein kann) oder den von der Hardware bereitgestellten Stack zu verwenden (der robuster und sicherer ist). –
Ein anderer Punkt ist, dass Compiler den Funktionsaufruf-Overhead optimieren, indem sie sorgfältig steuern, wie der Aufruf-Stack verwaltet wird. Zum Beispiel kann ein Aufruf einer einfachen Funktion durch den Compiler angeordnet werden, so dass die Funktion bestimmte Hardware-Register für ihre Arbeit frei verwenden kann, wodurch die Notwendigkeit vermieden wird, diese Register über einen Funktionsaufruf hinweg zu speichern und wiederherzustellen. Wenn Sie diese Dinge clever handhaben, erhalten Sie eine 20-30% ige Steigerung der CPU-Zeit, unabhängig von der Architektur, aber das bedeutet, dass der Aufruf-Stack für jede Funktion unterschiedlich sein kann, je nachdem, was der Optimierer getan hat. –
Ein Aufrufstapel ist eine Stapeldatenstruktur, die Informationen über die aktiven Unterprogramme eines Computerprogramms speichert.
Wo Thread-Stack ist, was ist der private Stapel eines Threads und Sie wissen darüber.
Wenn der Thread eine Funktion ausführt, wird die aktuelle Funktion call stack
in die thread stack
gespeichert.
Diese beiden Dinge sind im Wesentlichen die gleichen. Sie sind beide Stapel-Datenstrukturen.
Lesen [Call Stack.] (Https://en.wikipedia.org/wiki/Call_stack) Es ist genau das gleiche im Zusammenhang mit Threads auch. –
"Aufrufstapel" bezieht sich nur auf "Stapel". Stack ist eine verkürzte Darstellungsform. –