C ++ 11 std :: Threads vs Posix Threads

157

Dlaczego w praktyce powinienem preferować jednego lub drugiego? Jakie są różnice techniczne poza tym, że std::threadjest to klasa?

Shamdor
źródło
5
W praktyce powinieneś użyćstd::async
Stephan Dollberg
@bamboon This cierpi z takimi samymi problemami jak std::threadrobi
Gunther Piez
2
@hirschhornsalz z widoku obsługi kompilatora, tak. z technicznego punktu widzenia zapewnia wyjątkowy poziom bezpieczeństwa, który std::threadlub pthreadsnie.
Stephan Dollberg
15
Zagłosowano na ponowne otwarcie. Prośba o „różnice techniczne” sprawia, że ​​można na to obiektywnie odpowiedzieć. Wysoka liczba głosów wskazuje, że inni uznali ten post za konstruktywny i pomocny.
Adrian McCarthy
stackoverflow.com/questions/1273572/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

121

Jeśli chcesz uruchamiać kod na wielu platformach, przejdź do Posix Threads. Są dostępne prawie wszędzie i są dość dojrzałe. Z drugiej strony, jeśli używasz tylko Linuksa, / gcc std::threadjest całkowicie w porządku - ma wyższy poziom abstrakcji, naprawdę dobry interfejs i dobrze współpracuje z innymi klasami C ++ 11.

Klasa C ++ 11 std::threadniestety nie działa niezawodnie (jeszcze) na każdej platformie, nawet jeśli C ++ 11 wydaje się być dostępny. Na przykład w natywnym systemie Android std::threadlub Win64 po prostu nie działa lub ma poważne wąskie gardła wydajności (stan na 2012 r.).

Dobrym zamiennikiem jest boost::thread- jest bardzo podobny do std::thread(właściwie pochodzi od tego samego autora) i działa niezawodnie, ale oczywiście wprowadza kolejną zależność z biblioteki innej firmy.


Edycja: od 2017 std::threaddziała głównie na natywnym Androidzie. Niektóre klasy, takie jak, std::timed_mutexnadal nie są zaimplementowane.

Gunther Piez
źródło
19
Czy masz jakieś dowody na poparcie tych twierdzeń o „wąskim gardle wydajności”? Ponadto std::threadjego styl raii jest dobry, ponieważ obsługuje wyjątki C ++, podczas gdy pthreads nie mogą po wyjęciu z pudełka.
Jesse Good
9
Czy w 2014 roku ta odpowiedź jest nadal aktualna?
nonsensation
25
A co teraz, początek 2017 roku?
rmobis
9
A co teraz, w środku 2017 roku?
Wyścigi lekkości na orbicie
14
A co teraz, w środku 2018 roku?
陳 力
59

std::threadBiblioteka realizowana jest na górze pthreads w środowisku wspierającym pthreads (na przykład: libstdc ++).

Myślę, że dużą różnicą między nimi jest abstrakcja. std::threadjest biblioteką klas C ++. std::threadBiblioteka zawiera wiele abstrakcyjnych cech, na przykład: zamki, lunetą rekurencyjnych muteksy, przyszłość / obietnica implementacje wzorca projektowania i więcej.

Akira Takahashi
źródło
4
+1ode mnie za wskazanie najważniejszej rzeczy, a mianowicie, że std :: thread zapewnia wyższy poziom abstrakcji.
sbi
33

std::thread zapewnia przenośność na różnych platformach, takich jak Windows, MacOS i Linux.

Jak wspomniał @hirshhornsalz w komentarzach poniżej i powiązanej odpowiedzi https://stackoverflow.com/a/13135425/1158895 , std::threadmoże nie być jeszcze kompletna na wszystkich platformach. Mimo to (nastąpi to w najbliższej przyszłości) powinno być preferowane pthread, ponieważ powinno to uczynić twoją aplikację bardziej przyszłościową.

Brady
źródło
2
w rzeczywistości std :: thread zapewnia przenośność na wszystkich platformach, które obsługują C ++ 11, podczas gdy wątki POSIX są dostępne tylko na platformach POSIX (lub platformach, które dążą do minimalnej kompatybilności).
Tobias Langner
1
Z praktycznego punktu widzenia jest to po prostu błędne. Właściwie kilka miesięcy temu zdecydowałem się na to rozumowanie - to był poważny błąd. W praktyce musisz używać boost::threadna Win64 lub Bionic (Android), ponieważ std::threadwciąż brakuje dużych części, podczas gdy na Linuksie std::threadwydaje się dość dojrzały.
Gunther Piez
1
@hirschhornsalz, celem mojej odpowiedzi jest wskazanie korzyści z przenośności zapewnianej przez implementację wątku c ++ 11 w porównaniu z pthread. OP nie pytał o doładowanie, ale jest też przenośny.
Brady
3
@hirschhornsalz, jeśli chodzi o twój negatywny ton i oskarżenie, że nigdy nie używasz wątków, są one po prostu niekontrukcyjne i nie zasługują na duży wysiłek z mojej strony. Myślę, że warto przynajmniej wspomnieć, że bardziej konstruktywnym komentarzem byłoby wskazanie problemów, które miałeś podczas używania std :: thread na różnych platformach.
Brady
3
Podsumowując, c ++ 11 std :: thread jest użyteczne tylko z najnowszymi wersjami GCC. Nie jest prawie ukończona w programie Visual Studio, dlatego nie można jej używać w systemie Windows. I oczywiście brakuje go w komercyjnych kompilatorach na UNIX-ach (Sun Studio na Solaris, HP aCC na HP-UX, IBM vacpp na AIX). Dlatego, jeśli platformą docelową jest tylko Linux - c ++ 11 std :: thread jest w porządku; jeśli potrzebujesz także systemu Windows lub innego systemu UNIX - boost :: thread jest do zrobienia.
vond
7

Dla mnie decydującą różnicą techniczną jest brak prymitywów obsługi sygnału w std w przeciwieństwie do pthreads. Niezdolność do prawidłowego dyktowania obsługi sygnału w procesie uniksowym przy użyciu samego std jest AFAIK wyniszczającą wadą w używaniu std :: thread, ponieważ uniemożliwia ustawienie prawdziwego wielowątkowego wzorca obsługi sygnału do przetwarzania wszystkich sygnałów w dedykowanym wątku i zablokuj je w pozostałej części. Jesteś zmuszony założyć, że std :: thread jest zaimplementowany przy użyciu pthreads i mieć nadzieję na najlepsze, gdy używasz pthread_sigmask. Prawidłowa obsługa sygnałów nie podlega negocjacjom w programowaniu systemów Unix dla przedsiębiorstwa.

Od 2016 r. Std :: thread jest zabawką; proste.

Waslap
źródło
7
Nie zgadzam się. A intensywne wykorzystanie sygnałów to wzorzec projektowy, którego można uniknąć w większości zastosowań.
Erik Alapää
Zapewnia również std::threadbezpieczeństwo typu, którego nie ma pthread.
alfC
-3

OpenMP

http://www.openmp.org/

jest znormalizowanym, wielowątkowym standardem opartym na protokole SMP, który działa w systemach Linux i Windows już od ponad dziesięciu lat. OpenMP jest domyślnie dostępny we wszystkich kompilatorach, w tym GCC i Microsoft Visual Studio.

Jedną rzeczą, na którą należy zwrócić uwagę podczas korzystania z OpenMP, jest to, że jeśli jest więcej wątków niż rdzeni procesora, wydajność spadnie z powodu obciążenia związanego z przełączaniem kontekstu. Drugą rzeczą, o której należy pamiętać, jest to, że inicjalizacja wątku na rzeczywistym poziomie systemu operacyjnego jest stosunkowo kosztowna. Inicjalizacja trwa ułamek sekundy, ale w niektórych zastosowaniach bardzo małe frakcje gromadzą się ze znacznym kosztem.

W przypadku współbieżności związanej z wymaganiami architektury oprogramowania możesz chcieć poszukać implementacji „lekkich wątków” lub „zielonych wątków” zamiast używania OpenMP. Różnica polega na tym, że wątki OpenMP są rzeczywistymi wątkami na poziomie systemu operacyjnego, ale „zielone wątki” mogą być po prostu „wątkami symulowanymi”, które są wykonywane przy użyciu niewielkiej liczby rzeczywistych wątków.

Martin Vahi
źródło
6
Bez braku szacunku, ale jak to się ma do głównego pytania?
SRG