12

C++ 11 ma pewne pojęcie wątków. Na przykład definiuje nowy specyfikator pamięci thread_local i określa, że ​​w przypadku zmiennych z tym specyfikatorem pamięci "istnieje odrębny obiekt lub odniesienie dla wątku" [basic.stc.thread].Co C++ 11 uważa za "wątek"?

Co jest uważane za "wątek" w tym celu? Czy jest to tylko wątek utworzony przy użyciu standardowej biblioteki wątków (tj. Reprezentowanych przez obiekty std::thread)? A co z wątkami tworzonymi innymi metodami (na przykład, używając pthreads bezpośrednio na Linuksie)? Co się stanie, jeśli użyję biblioteki udostępniającej wątki przestrzeni użytkownika - czy każdy z nich otrzyma własne kopie obiektów (naprawdę nie rozumiem, jak można to zaimplementować)?

Jeśli odpowiedź brzmi "jest zdefiniowana przez implementację, co jest uważane za wątek do celów takich jak thread_local", czy ktoś mógłby podać przykład tego, jak definiuje to jedna z dobrze znanych implementacji?

+0

@texasbruce Java * teraz * zawiera te słowa kluczowe? Byli tam 17 lat temu. – EJP

Odpowiedz

3

Tylko składniki z biblioteki obsługi wątków są liczone z powodu tych ofert lub main, których standardowe stany działają we własnym wątku wykonywania.

1 następujące podrozdziały opisu składników do tworzenia i zarządzania zwojów (1,10), wykonywania wzajemnego wykluczenia oraz przedstawienia zasad i wartości pomiędzy gwintem, jak przedstawiono w tabeli 148.

odnośnik do 1.10 oznacza, że ​​mówione są te wątki.

1 wątek wykonania (znany również jako wątku) jest pojedynczym przepływem kontroli w ramach programu, w tym początkowe ...

Dlatego wydaje mi wątki odnoszą się tylko do wątków stdlib (co oznacza std :: thread i wszystko, co wewnętrznie obsługuje biblioteka obsługi wątków). Oczywiście thread_local w wielu przypadkach może skończyć się pracą z natywnymi wątkami (szczególnie jeśli weźmiesz pod uwagę konkretny system, który zazwyczaj nie ma więcej niż jednego wyboru do implementacji wątków), ale o ile mogę powiedzieć, że standard nie daje żadnej gwarancji.

+0

Chociaż jest to prawdą i implementacje mogłyby technicznie uciec z obsługą 'thread_local' tylko z' std :: thread', byłoby to słabą implementacją jakości. Dotychczasowe implementacje zapewniają, że 'thread_local' działa z wątkami systemowymi i ma' std :: thread' pobiera wsparcie dla 'thread_local' przez obsługę biblioteki wątków systemowych. – bames53

+1

@ bames53 nie wiem, jak to dotyczy mojej odpowiedzi, wszystko, co mówię, to to, że "wątek" w C++ jest czymś, co jest zaimplementowane wewnętrznie, 'std :: thread' jest oczywiście jednym z nich, ale inne rzeczy wewnętrznie mogą produkować wątek". Nawet jeśli wewnętrznie używają implementacji, powiedzmy "pthreads", a kończą jako "wątek", który standard daje gwarancję tej IMO. – aaronman

+0

Tak, zgadzam się z tobą, że standard nie gwarantuje niczego innego niż 'std :: thread'. Dodaję, że w praktyce i implementacjach, które znam, 'thread_local' będzie działał z wątkami systemu, a nie tylko' std :: thread'. – bames53

0

Standard nie opisuje sposobu zachowania wątków tworzonych przez inne biblioteki i wywołania systemowe. Są one, o ile chodzi o standard, nieokreślone w ich zachowaniu. Nie ma innego sposobu, w obrębie C++ właściwego, do tworzenia wielu wątków: takie biblioteki lub wywołania systemowe robią rzeczy, które nie są standaryzowane przez standard C++.

Teraz każda taka biblioteka i wywołanie systemowe będą zachowywać się w sposób zdefiniowany przez własne specyfikacje. Dość często C++ std::thread będzie nawet zbudowany na takich bibliotekach lub wywołaniach systemowych. Sposób działania interakcji nie jest określony.

3

C++ 11 §1.10/1 określa warunki:

wątek wykonania (znany również jako nici) jest pojedynczym przepływem kontroli w programie, w tym początkowym wywołanie konkretnej funkcji najwyższego poziomu i rekursywnie włączając wszystkie wywołania funkcji wykonywane następnie przez wątek.[Uwaga: Gdy jeden wątek tworzy inny, początkowe wywołanie funkcji najwyższego poziomu nowego wątku jest wykonywane przez nowy wątek, a nie przez tworzony wątek. - koniec uwaga]

W kursywą warunki wskazują, że jest to ostateczne. Można argumentować, że ta definicja jest matematycznie niewystarczająca, ponieważ każda inwokacja funkcji definiuje nowy wątek, ale jest to oczywiście błędne. Chodzi o pojedynczy przepływ kontroli, w przeciwnym razie nienormatywna nuta anulowałaby efekt normatywnego tekstu "rekursywnie włącznie".

Z punktu widzenia języka podstawowego, jest tylko przypadkowe, że takie coś istnieje. std::thread

Co jeśli używam biblioteki, która zapewnia łatwy wątki przestrzeń - czy każdy z tych dostać swoje kopie thread_local obiektów (I naprawdę nie rozumiem, jak to może być realizowane)?

Nie ma sposobu na napisanie takiej biblioteki bez wywołań jądra. Najprawdopodobniej wszystkie wątki w twoim procesie są już reprezentowane przez abstrakcję wysokiego poziomu, taką jak pthreads, tylko po to, aby zadowolić jądro. Biblioteka standardowa C++ jest prawdopodobnie napisana w stosunku do rodzimej biblioteki wątków do "po prostu działa" bez dodatkowego kleju.

Na przykład obiekty thread_local są inicjowane przy pierwszym dostępie, a nie przy każdym nowym wątku, więc kompilator musi tylko wstawić zapytanie oparte na pthread_self, aby uzyskać dostęp i być może zainicjować. Inicjalizacja rejestrowałaby destruktor w obiekcie pthread_cleanup.

Definicja implementacji określa, czy istniejąca biblioteka natywna jest zgodna z C++. Przypuśćmy, że to zapewnią, a jest to coś, czego klienci chcieliby mieć, wszystkie inne biblioteki wątków wbudowane w nie będą automatycznie kompatybilne z innymi konfliktami.

+0

Tak więc, aby właściwie odpowiedzieć na pytanie OP, wierzysz wszystko, co tworzy nowy strumień kontroli w programie, gwarantuje pracę z czymś takim jak "thread_local" przez standard – aaronman

+0

@aaronman Yep. Dodam kolejną uwagę, aby wyjaśnić ... – Potatoswatter