2012-02-20 17 views
12

Myślałem o std::async i jak należy go używać w przyszłej implementacji kompilatora. Jednak w tej chwili utknąłem w czymś, co wydaje mi się wadą projektu.std :: async - Użycie zależne od implementacji?

The std::async jest zależny od implementacji, z prawdopodobnie dwoma wariantami launch::async, jednym, który uruchamia zadanie w nowym wątku i takim, który używa puli wątków/harmonogramu zadań.

Jednak w zależności od jednego z tych wariantów, które są używane do implementacji std::async, użycie będzie bardzo różne.

Dla wariantu opartego na "puli wątków" można uruchomić wiele małych zadań, nie martwiąc się zbytnio o koszty ogólne, ale co, jeśli jedno z zadań blokuje w pewnym momencie?

Z drugiej strony wariant "uruchom nowy wątek" nie miałby problemów z blokowaniem zadań, z drugiej strony obciążenie związane z uruchamianiem i wykonywaniem zadań byłoby bardzo wysokie.

thread-pool: + nisko nad głową, -Nigdy kiedykolwiek blokowania

uruchamiają nowy wątek: + grzywny z bloków, -high napowietrznych

Więc zasadniczo w zależności od implementacji, sposób, w jaki używamy std::async, byłby bardzo ostrożny. Jeśli mamy program, który działa dobrze z jednym kompilatorem, może działać strasznie na innym.

Czy jest to zgodne z projektem? Czy może czegoś brakuje? Czy uznałbyś to, tak jak ja, za duży problem?

W obecnej specyfikacji brakuje czegoś takiego, jak std::oversubscribe(bool), aby umożliwić wdrożenie zależnego od siebie użycia std::async.

EDYCJA: O ile przeczytałem, standardowy dokument C++ 11 nie daje żadnych wskazówek dotyczących tego, czy zadania wysłane do std::async mogą blokować, czy nie.

+0

Tak samo jako dodatek: http://en.cppreference.com/w/cpp/thread/async dostarcza całkiem prostego i realistycznego przykładu blokowania wywołań 'std :: async'. – KillianDS

+0

Wydaje się, że zakładasz, że pule wątków mają stały rozmiar. W praktyce wiele z nich ma rozmiar dynamiczny, więc blokowanie nie jest problemem. –

+0

@MooingDuck: Ani TBB ani Concrt nie mają "dynamicznie" wielkości pul wątków. Jakie pule wątków wiesz o tym są dynamiczne? I nawet jeśli masz pulę wątków o dynamicznym rozmiarze, zamiast tego pojawia się problem nadsubskrypcji i nakłady heurystyczne są potrzebne, aby śledzić, kiedy dodawać nowe wątki i usuwać stare. – ronag

Odpowiedz

11

std::async zadania uruchamiane z polityką std::launch::async metę „jakby w nowym wątku”, więc baseny wątek nie są naprawdę obsługiwane --- runtime musiałaby zburzyć i odtworzyć wszystkie zmienne lokalne w wątku między sobą wykonywanie zadań, co nie jest proste.

Oznacza to również, że można oczekiwać jednoczesnego uruchamiania zadań rozpoczętych przy użyciu zasady std::launch::async.Może pojawić się opóźnienie uruchomienia i nastąpi przełączanie zadań, jeśli masz więcej uruchomionych wątków niż procesorów, ale powinny działać, a nie zakleszczenie tylko dlatego, że ktoś czeka na innego.

Implementacja może zaoferować rozszerzenie, które pozwala na uruchamianie zadań w puli wątków, w takim przypadku to do tej implementacji jest udokumentowanie semantyki.

+1

+1, dla "jak gdyby w nowym wątku" i zmienne lokalne wątku. – ronag

+0

Asynchronizacja MSVC używa wątku. Wyobrażam sobie, kiedy wątek kończy "zadanie", raportuje zakończenie, a następnie resetuje loci wątków, a następnie czeka na nowe zadanie. Oznaczałoby to, że kod użytkownika nigdy nie musi czekać na reset lokalny wątku. –

+0

Nie znam szczegółów implementacji MSVC, jednak standard wymaga, aby zmienne 'thread_local' zostały zniszczone przed przygotowaniem' future'. –

1

Spodziewam się, że implementacje uruchomią nowe wątki i pozostawią pulę wątków w przyszłej wersji C++, która je standaryzuje. Czy są jakieś implementacje, które używają puli wątków?


MSVC użył początkowo puli wątków w oparciu o ich Środowisko wykonawcze Współbieżności. Według STL Fixes In VS 2015, Part 2 zostało to usunięte. Specyfikacja C++ pozostawiła nieco miejsca dla programistów na robienie sprytnych rzeczy, ale nie sądzę, że pozostawia wystarczająco dużo miejsca na tę implementację łączenia wątków. W szczególności uważam, że specyfikacja nadal wymagała, aby obiekty thread_local zostały zniszczone i przebudowane, ale ta kombinacja wątków z ConcRT nie wspierałaby tego.

+1

Jeśli dobrze pamiętam, Microsoft ogłosił podczas konferencji Going Native 2012, że 'std :: async' użyje Concrt. Nie wiem, jakie plany ma gcc i clang. – ronag

+0

MSVC w tym miejscu korzysta z tego wątku, ani libC++ ani libstdC++ nie używają ostatnio używanych pul. –

Powiązane problemy