2009-11-03 13 views
103

O ile mi wiadomo, każdy wątek otrzymuje odrębny stos, gdy wątek jest tworzony przez system operacyjny. Zastanawiam się, czy każda nić ma stertę odrębną dla siebie?Czy wątki mają wyraźną kupę?

+1

Jaka platforma i biblioteka c? – divegeek

+0

tak, windows i linux, c biblioteka – root

+2

Nice. +1 utrzymuj te podstawowe pytania. –

Odpowiedz

110

Nie. Wszystkie wątki mają wspólną kupkę.

Każdy thread has a private stack, który może szybko dodawać i usuwać elementy. Powoduje to szybką pamięć opartą na stosie, ale jeśli użyjesz zbyt dużej ilości pamięci stosu, co występuje w nieskończonej rekursji, dostaniesz przepełnienie stosu.

Ponieważ wszystkie wątki mają tę samą stertę, należy zsynchronizować dostęp do alokatora/deallocator. Istnieją różne metody i biblioteki do uniknięcia allocator contention.

Niektóre języki umożliwiają tworzenie prywatnych pul pamięci lub pojedynczych stert, które można przypisać do pojedynczego wątku.

+0

To zależy od środowiska wykonawczego. – divegeek

+5

Zazwyczaj wątki współużytkują zasoby, takie jak pamięć, aby każda implementacja wątku innego niż braintead udostępniała stertę. –

+10

Głównym powodem, dla którego każdy wątek ma własny stos, jest to, że wątek może faktycznie coś (np. Wywoływanie funkcji) ... – Edmund

1

Zazwyczaj wątki współużytkują stertę i inne zasoby, jednak istnieją konstrukcje podobne do wątków, które tego nie robią. Pośród tych konstrukcji przypominających wątki są lekkie procesy Erlanga i pełne procesy UNIX (utworzone za pomocą połączenia z fork()). Możesz także pracować na współbieżności wielu maszyn, w takim przypadku opcje komunikacji między wątkami są znacznie bardziej ograniczone.

+0

Myślałem, że fork był raczej jak tworzenie nowego procesu, który właśnie skopiował dane do nowej lokalizacji pamięci. –

+2

fork() może służyć w wielu przypadkach użycia, w których można również używać wątków. Ze względu na kopiowanie przy zapisie, nie ma znaczącej różnicy kosztów w systemach uniksowych. Typowy przypadek użycia to sytuacja, w której pracownik jest niezależny (np. Serwer sieciowy) od reszty usługi. Inną możliwością jest komunikowanie się za pośrednictwem standardowego wejścia/wyjścia z głównym wątkiem/programem. fork() działa silnie na Uniksie, podczas gdy inne platformy, takie jak Windows wolą wątki.Głównym powodem prawdopodobnie jest to, że używanie fork() jest znacznie prostsze i bezpieczniejsze, a Unix ma tę prostą filozofię. Zobacz na przykład serwer WWW Apache z jego powolnym przejściem do wątków. – ypnos

9

Domyślnie C ma tylko jedną stertę.

Powiedziawszy, niektóre alokatory, które znają wątek, podzieliją stertę, tak aby każdy wątek posiadał własny obszar do przydzielenia. Chodzi o to, że powinno to poprawić skalę sterty.

Jednym z przykładów takiej sterty jest Hoard.

+0

Domyślnie C i C++ nie mają wielu wątków. Specyfikacja C++ 2003 przynajmniej nie uwzględnia żadnych wątków w projekcie maszyny wirtualnej, więc wątki w C++ są zdefiniowane przez implementację. –

+0

Nawet jeśli różne wątki mają różne obszary do przydzielenia na stercie, nadal będą widzieć dane przydzielone przez inny wątek, więc wątki nadal będą współdzielić tę samą stertę. –

+1

Aktualizacja: od C++ 11 wątków nie jest już definiowanych przez implementację. – anthropomorphic

3

Każdy wątek ma własny stos i stos wywoławczy.

Każdy wątek dzieli tę samą stertę.

1

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 Thread Local Storage (TLS), ale przechowuje tylko pojedyncze wartości.

Windows szczegółowy: TLS-przestrzeń może zostać przydzielone za pomocą TlsAlloc a zwolnione przez TlsFree (Przegląd here). Ponownie, to nie jest kupa, tylko DWORD.

Co dziwne, system Windows obsługuje wiele procesów Heaps. Można przechowywać uchwyt hełmu w TLS. Wtedy miałbyś coś w rodzaju "Lokalnego kupra nici". Jednak tylko uchwyt nie jest znany innym wątkom, nadal może uzyskać dostęp do swojej pamięci za pomocą wskaźników, ponieważ wciąż jest to ta sama przestrzeń adresowa.

EDIT: Niektóre podzielniki pamięci (konkretnie jemalloc na FreeBSD) używają TLS, aby przypisać "aren" do gwintów. Odbywa się to w celu optymalizacji alokacji dla wielu rdzeni poprzez zmniejszenie narzutów synchronizacji.

+0

> "Dziwnie, Windows obsługuje wiele kupek na proces.", To wcale nie jest dziwne, można użyć różnych stosów dla różnych rodzajów przydziałów, po prostu dodaje więcej elastyczności. Oczywiście zawsze możesz dostać się do VirtualAlloc i zbudować własną kupę, jak tylko chcesz. –

5

Zależy od systemu operacyjnego. Standardowe środowisko wykonawcze c w oknach i unice używa wspólnej sterty dla wątków. Oznacza to zablokowanie każdego malloc/free.

Na przykład w systemie Symbian każdy wątek ma własny stos, chociaż wątki mogą współdzielić wskaźniki z danymi przydzielonymi w dowolnej stercie. Konstrukcja Symbiana jest w mojej opinii lepsza, ponieważ nie tylko eliminuje potrzebę blokowania podczas alokacji/bezpłatnego, ale także zachęca do czystej specyfikacji własności danych między wątkami. Również w tym przypadku, gdy wątek umiera, pobiera wszystkie obiekty, które mu przydzielono - tj. Nie może przeciekać przydzielonych przez siebie obiektów, co jest ważną właściwością dla urządzeń mobilnych z ograniczoną pamięcią.

Erlang również stosuje podobny układ, w którym "proces" działa jako jednostka gromadzenia śmieci. Wszystkie dane są przekazywane między procesami przez kopiowanie, z wyjątkiem binarnych obiektów blob, które są liczone jako odniesienie (chyba).

2

To zależy od tego, co dokładnie masz na myśli mówiąc "kupa".

Wszystkie wątki współużytkują przestrzeń adresową, więc obiekty przydzielane sterty są dostępne ze wszystkich wątków. Z technicznego punktu widzenia stosy są również udostępniane w tym sensie, tzn. Nic nie uniemożliwia dostępu do stosu innych wątków (chociaż prawie nigdy nie miało to sensu).

Z drugiej strony istnieją sterty struktur używane do alokowania pamięci. Tutaj odbywa się cała księgowość przydzielania pamięci sterty. Struktury te są wyrafinowane, aby zminimalizować rywalizację między wątkami - więc niektóre wątki mogą współdzielić strukturę stosu (arenę), a niektóre mogą korzystać z odrębnych aren.
Zobacz wątku dla doskonałego wyjaśnienia szczegółów: How does malloc work in a multithreaded environment?

+0

+1: nikt nie powiedział, że stos (wywołanie) jest również udostępniony. – user2431763

1

W systemie operacyjnym FreeRTOS, zadania (wątków) podziela tą kupę, ale każdy z nich ma swój własny stos. Jest to bardzo przydatne, gdy mamy do czynienia z architekturami o niskim poborze mocy z niską pamięcią RAM, ponieważ ta sama pula pamięci może być udostępniana/dzielona przez kilka wątków, ale jest to przy niewielkim haczyku, deweloper musi pamiętać, że mechanizm synchronizacji malloc i jest potrzebna, dlatego konieczne jest użycie pewnego rodzaju synchronizacji/blokady procesu podczas przydzielania lub zwalniania pamięci na stercie, na przykład semafora lub muteksa.