2010-06-26 12 views
9

Chciałbym rozpocząć naukę wielowątkowości w C++. Uczę się go również w Javie. W Javie, jeśli napiszę program, który używa wielowątkowości, będzie działał w dowolnym miejscu. Jednak w C++, wielowątkowość nie opiera się na API specyficznym dla platformy? Jeśli tak, to wydaje się, że przeszkadza to w przenoszeniu.Wielowątkowość w C++ ... od czego zacząć?

Jak wykonać wielowątkowość w C++ bez powodowania problemów z przenośnością? Czy biblioteka boost to thread dobre rozwiązanie?

Jako sidenote - w jaki sposób można nawet zaimplementować wielowątkowość jako bibliotekę? Czy nie jest to coś, co musi zrobić kompilator?

+1

Jako słowo ostrożności, będziesz musiał pomyśleć o wiele więcej na temat bezpieczeństwa wątków w C++. Nie można po prostu posypać synchronizujących słów kluczowych metodami klasowymi, aby były bezpieczne dla wątków. Generalnie będziesz używać narzędzi takich jak muteksy lub inne formy sekcji krytycznych, operacji atomowych itp. Jednak, jeśli zrobisz to dobrze, będziesz w stanie napisać bardzo wydajny kod wielowątkowy. Możesz nawet pisać własne alokatory pamięci z pulami pamięci dla wielu wątków, ale jest to znacznie niższy poziom i znacznie trudniejsze do napisania dla poprawności niż Java. – stinky472

+0

(+1) @ stinky472: Właśnie dlatego chcę nauczyć się wielowątkowości w C++ oraz w Javie. Uważam, że Java jest ogólnie dobra do wprowadzania na wysokim poziomie wielu tematów, ale po prostu trzymanie się Javy może uratować programistę trochę za bardzo i nie narazić ich na kilka bardzo ważnych pojęć. Dlatego, podczas gdy uczę się wielowątkowości w Javie, chcę jednocześnie nauczyć się go w C++, aby upewnić się, że uczę się wszystkiego, czym powinienem być. – Cam

Odpowiedz

13

Jeśli nie masz kompilatora, który obsługuje C++0x jeszcze (dostępne z visual studio C++ 2010 na przykład), przypominającego stosowanie nici. (O ile nie korzystasz z frameworka, który obsługuje już wątkowanie, co nie jest prawdą - nie zadawałbyś tego pytania w inny sposób -). Wzmocnione wątki stały się standardem w zupełnie nowym C++. Przedtem C++ sam był wątkiem nieświadomym.

może być również interesujące dla ciebie, jeśli chcesz nauczyć się innych aspektów programowania równoległego.

Odnośnie Qt: jeśli potrzebujesz tylko obsługi wątków, oznacza to całkowitą przesadę. Ma strasznie powolny czas podróży w obie strony, od kompilacji do wyniku. To naprawdę dobrze zaprojektowana myśl. Ale nie oficjalny standard, jak wątki C++ 0x z boost. Dlatego nie brałbym tego jako pierwszego wyboru.

+0

Dzięki. Wszystkie odpowiedzi były bardzo wyczerpujące, ale ta była najbardziej interesująca. – Cam

3

W C++, taktykanie jest specyficzne dla platformy. Jednak wiele bibliotek wątków zawiera niuanse wątków na różnych platformach, zapewniając jednolity interfejs API do pisania aplikacji z gwintami, dzięki czemu nie musisz się martwić szczegółami związanymi z platformą.

Biblioteka doładowania gwintów to bardzo dobre rozwiązanie.

Polecam również sprawdzenie numeru ACE.

1

Aby zaoferować propozycję inną niż Boost, używam Pthreads (lub Pthreads-Win32 na Windows). Jest to biblioteka typu "zrób to sam" barebones, ale zapewnia wszystko, czego potrzebujesz i nic więcej. Jest bardzo lekki w porównaniu do Boosta i możesz łatwo znaleźć wokół niego wrappery C++, aby uzyskać wyższą poziom abstrakcji.

+0

Biblioteka wątków z doładowania jest biblioteką "tylko nagłówkową" szablonu. Nie powoduje dużego obciążenia. Ok mnóstwo potrzebnych plików może być ogromna, ale w ostatecznym wyniku będziesz miał tylko kilka bajtów z instancji szablonu. – jdehaan

+0

@jdehaan: Czy możesz rozwinąć to, co masz na myśli przez "tylko" nagłówek "szablonu"? – Cam

+3

Muszę przyznać, że jestem dość zaskoczony również "tylko nagłówkiem". To: 'libboost_thread-vc100-mt-gd-1_43.lib' nie wygląda jak nagłówek. –

4

Zacznijmy od tyłu:

Jak to jest możliwe do wykonania gwintu w bibliotece?

Nie jest, przynajmniej nie w (czystym) C++. Wymaga to obsługi języka (kompilator jest tylko implementacją).

Obecnie 2 rzeczy są używane:

  • kodu montażowym do niektórych części (jak w bibliotece pthread)
  • szczegółowych instrukcji kompilatora dla innych (w zależności od kompilatora i platformy)

Obie są kruche i wymagają ogromnej ilości pracy do przenoszenia. Zasadniczo oznacza to wiele części w kodzie, aby przetestować kompilator i docelową architekturę, przetestować obsługę niektórych dyrektyw itp. ...

Dlatego uznano, że konieczne jest dodanie obsługi wątków w C++ 0x .

Jak wykonać wielowątkowość?

Jeszcze przed wyborem biblioteki należy wybrać metodę. Istnieją 2 sposoby programowania aplikacji wielowątkowych (i można je połączyć):

  • komunikować się poprzez dzielenie: oznacza to, używając muteksy, operacje atomowe, itp ... można użyć pthread na platformach Linux, ale poleciłabym Boost.Thread (między innymi) za jego przenośność.
  • Udostępnij, komunikując się: nowsze i dostosowane do rozproszonych obliczeń, wynika to z języków funkcjonalnych. Oznacza to przekazywanie wiadomości z jednego wątku do drugiego i nie dzielenie się żadnymi zasobami. Możesz użyć FastFlow lub Intela Thread Building Blocks aka TBB.

Można połączyć dwa, ale lepiej byłoby nie. Osobiście uważam, że opis FastFlow jest całkowicie niesamowity: zachęca do programowania bez blokady. Główną zaletą drugiej metody jest to, że jest lepiej dostosowana do programowania wielu procesów i skal do rozproszonych środowisk.

Na początek polecam skupienie się na jednym i zbudowanie z nim niektórych aplikacji. Kiedy czujesz się komfortowo, możesz wypróbować drugą, ale bądź gotowy, aby rozpocząć od nowa.

+0

To nie jest kompilator do obsługi wątków, to do systemu operacyjnego. Przykładowo, w C++, to na przykład nagłówki pthreads, użyj jego funkcji i linku do biblioteki lib. Kompilator nic nie wie o samym Pthreads. – Gianni

+0

Cóż, powiedziałbym, że używanie biblioteki opartej na złożeniu nie używa czystego C++;) Naprawię jednak kompilator, miałem na myśli język. –

+0

@Matthieu chodziło mi o to, że aplikacja prosi tylko system operacyjny o wątek, a do systemu operacyjnego - o utworzenie i zainicjowanie wątku. ASM lub wbudowane funkcje kompilatora (co oznacza więcej ASM) są używane tylko dla atomów. Mutexy, Semafory, same wątki - wszystko zależy od systemu operacyjnego. – Gianni

1

możesz również rozważyć openmp http://openmp.org. Obsługuje go wiele kompilatorów, w tym MS, GCC/G ++ i Intel. Chociaż nie można uzyskać wyraźnej kontroli nad wątkami, jej wyższego poziomu równoległość jest czasami bardziej wydajna (zarówno w czasie kodowania, jak i w czasie wykonywania), a kod jest znacznie łatwiejszy do zrozumienia. Nie pomoże ci to zbytnio, jeśli pracujesz z GUI, ale przy skalowalnych obliczeniach warto się przyjrzeć.

1

Biblioteka Boost Threading jest prawdopodobnie najlepszym miejscem do rozpoczęcia C++. Daje ci wątkowanie obiektów, a także wszystkie muteksy i obiekty kontrolne, których potrzebujesz do napisania działającej wielowątkowej aplikacji.

0

Jeśli robisz to w interesie, aby poszerzyć swoją wiedzę na temat różnych modeli programowania i umiejętności językowych, to biblioteka Boost byłaby dobrym sposobem. Jednak bardzo długo zastanawiałbym się nad faktycznym budowaniem aplikacji produkcyjnych wykorzystujących wielowątkowe C++.

C++ jest czasem wystarczającym wyzwaniem, aby uzyskać poprawność, bez zwiększania złożoności wielowątkowości w pamięci współdzielonej. Nawet najbardziej doświadczeni programiści zgodziliby się, że wielowątkowe programy są niezwykle trudne do zrozumienia i poprawne. Nawet najprostsze programy mogą szybko stać się trudne do przetestowania i debugowania po wielowątkowym.

Języki imperatywne, takie jak C++ lub Java lub C# (z ich zmiennymi zmiennymi, pamięcią wspólną i prymitywami blokującymi/sygnalizacyjnymi) są bardzo często najmniej przystępnym sposobem na próbę tworzenia aplikacji wielowątkowych. Zwykle są to doskonałe, jednoznaczne opcje implementacji, które pozwalają rozwiązać większość problemów związanych z przestrzenią użytkownika (w przeciwieństwie do jądra lub wbudowanych), w tym na komputerach wielordzeniowych.

Jeśli naprawdę chcesz zbudować niezawodne aplikacje "wielowątkowe", sugeruję wypróbowanie języków funkcyjnych, takich jak Erlang, Haskell, F # lub Clojure.

2
//This program explains how pthread works, here 5 thread are trying to update a global variable simultaneously but with locking synchronization in maintained 
#include<iostream> 
#include<pthread.h> 
using namespace std ; 

#define MAX_NO_THREAD 5 

    int global_sum = 0 ; 
    pthread_mutex_t lock ; //Declared global lock mutex object 

void *print_fun(void *arg) 
{ 
    cout<<"\nThread id : "<<(int)arg; 
    pthread_mutex_lock(&lock) ; //aquiring lock on piece of code 
    for (int j=0; j<100000000; j++) 
    { 
     global_sum++ ; 
    } 
    pthread_mutex_unlock(&lock) ; //reomving lock on peice of code 
    cout<<"\nGlobal Sum : "<<global_sum ; 
} 

int main() 
{ 
    int i = 0 ; 
    pthread_t threads_obj[MAX_NO_THREAD] ; //Initializing object array for thread 
    pthread_mutex_init(&lock, NULL) ; //Initalinzing lock object for thread 
    int st ; 
    for (i=0; i<5; i++) 
    { 
     pthread_create(&threads_obj[i], NULL, *print_fun, (void *)i) ;//Initializing threads calling function print_fun 
     pthread_join(threads_obj[i], 0) ; //Forcing main thread to main until these thread complete 
    } 
    pthread_mutex_destroy(&lock) ; //Destroying lock object 
} 



//compile this program using -lpthread option with g++ 
//g++ thread.cc -lpthread 
Powiązane problemy