O ile wiem, każdy wątek otrzymuje oddzielny stos, gdy wątek jest tworzony przez system operacyjny. Zastanawiam się, czy każdy wątek ma również własny stos?
O ile wiem, każdy wątek otrzymuje oddzielny stos, gdy wątek jest tworzony przez system operacyjny. Zastanawiam się, czy każdy wątek ma również własny stos?
Odpowiedzi:
Nie. Wszystkie wątki mają wspólny stos.
Każdy wątek ma prywatny stos , z którego może szybko dodawać i usuwać elementy. To sprawia, że pamięć oparta na stosie jest szybka, ale jeśli użyjesz zbyt dużej ilości pamięci stosu, jak to ma miejsce w przypadku nieskończonej rekurencji, nastąpi przepełnienie stosu.
Ponieważ wszystkie wątki współużytkują tę samą stertę, dostęp do alokatora / dezalokatora musi być zsynchronizowany. Istnieje wiele metod i bibliotek pozwalających uniknąć rywalizacji o alokatory .
Niektóre języki umożliwiają tworzenie prywatnych pul pamięci lub pojedynczych stert, które można przypisać do pojedynczego wątku.
you will get a stack overflow.
Przepełnienie stosu na Stack Overflow!
Domyślnie C ma tylko jedną stertę.
To powiedziawszy, niektóre alokatory, które są świadome wątków, podzielą stertę na partycje, tak aby każdy wątek miał swój własny obszar do przydzielenia. Chodzi o to, że powinno to poprawić skalowanie sterty.
Jednym z przykładów takiej kupy jest Hoard .
Zależy od systemu operacyjnego. Standardowe środowisko uruchomieniowe c w systemie Windows i unices wykorzystuje stertę współdzieloną między wątkami. Oznacza to zablokowanie każdego malloc / free.
Na przykład w systemie Symbian każdy wątek ma swoją własną stertę, chociaż wątki mogą udostępniać wskaźniki do danych przydzielonych w dowolnej stercie. Projekt Symbiana jest moim zdaniem lepszy, ponieważ nie tylko eliminuje potrzebę blokowania podczas przydzielania / zwolnienia, ale także zachęca do czystego określania własności danych między wątkami. Również w tym przypadku, gdy wątek umiera, zabiera wszystkie obiekty, które zaalokował wraz z nim - tj. Nie może wyciekać obiektów, które przydzielił, co jest ważną właściwością w urządzeniach mobilnych z ograniczoną pamięcią.
Erlang również stosuje podobny projekt, w którym „proces” działa jako jednostka usuwania śmieci. Wszystkie dane są przesyłane między procesami przez kopiowanie, z wyjątkiem binarnych obiektów blob, do których liczone są odwołania (tak mi się wydaje).
Zależy to od tego, co dokładnie masz na myśli, mówiąc „sterta”.
Wszystkie wątki współdzielą przestrzeń adresową, więc obiekty przydzielone na sterty są dostępne ze wszystkich wątków. Technicznie, stosy są również współdzielone w tym sensie, tj. Nic nie stoi na przeszkodzie, abyś uzyskał dostęp do stosu innego wątku (chociaż prawie nigdy nie miałoby to sensu).
Z drugiej strony istnieją struktury sterty używane do przydzielania pamięci. To tam odbywa się cała księgowość alokacji pamięci sterty. Struktury te są wyrafinowane, aby zminimalizować rywalizację między wątkami - więc niektóre wątki mogą mieć wspólną strukturę sterty (arenę), a niektóre mogą używać odrębnych aren.
Zobacz poniższy wątek, aby uzyskać doskonałe wyjaśnienie szczegółów: Jak działa malloc w środowisku wielowątkowym?
Zwykle wątki współużytkują stertę i inne zasoby, jednak istnieją konstrukcje podobne do wątków, które tego nie robią. Wśród tych wątkowych konstrukcji znajdują się lekkie procesy Erlanga i pełne procesy UNIX (tworzone za pomocą wywołania fork()
). Możesz również pracować z współbieżnością wielu maszyn, w takim przypadku opcje komunikacji między wątkami są znacznie bardziej ograniczone.
Ogólnie rzecz biorąc, wszystkie wątki używają tej samej przestrzeni adresowej i dlatego zwykle mają tylko jedną stertę.
Jednak może to być nieco bardziej skomplikowane. Być może szukasz lokalnego magazynu wątków (TLS), ale przechowuje on tylko pojedyncze wartości.
Specyficzne dla systemu Windows: przestrzeń TLS można przydzielić za pomocą TlsAlloc i zwolnić za pomocą TlsFree (przegląd tutaj ). Ponownie, to nie jest kupa, tylko DWORDy.
O dziwo, system Windows obsługuje wiele stert na proces. Uchwyt Heap można przechowywać w TLS. Wtedy miałbyś coś takiego jak „Sterta lokalna wątku”. Jednak tylko uchwyt nie jest znany innym wątkom, nadal mogą uzyskać dostęp do jego pamięci za pomocą wskaźników, ponieważ nadal jest to ta sama przestrzeń adresowa.
EDYCJA : Niektóre alokatory pamięci (szczególnie jemalloc we FreeBSD) używają TLS do przypisywania „aren” do wątków. Ma to na celu zoptymalizowanie alokacji dla wielu rdzeni poprzez zmniejszenie obciążenia synchronizacji.
W systemie operacyjnym FreeRTOS zadania (wątki) mają tę samą stertę, ale każde z nich ma swój własny stos. Jest to bardzo przydatne w przypadku architektur o niskim poborze mocy i małej pamięci RAM, ponieważ ta sama pula pamięci może być dostępna / współdzielona przez kilka wątków, ale wiąże się to z małym haczykiem, programista musi pamiętać, że mechanizm synchronizacji malloc i wolne jest potrzebne, dlatego konieczne jest użycie pewnego rodzaju synchronizacji / blokady procesu podczas przydzielania lub zwalniania pamięci na stercie, na przykład semafora lub muteksu.