logo

Wielowątkowość w C++

Wielowątkowość to funkcja umożliwiająca jednoczesne wykonywanie dwóch lub więcej części programu w celu maksymalnego wykorzystania procesora. Każda część takiego programu nazywana jest wątkiem. Zatem wątki są lekkimi procesami w procesie.

listy lateksowe

Obsługa wielowątkowości została wprowadzona w C++ 11. Przed C++ 11 musieliśmy używać Wątki lub biblioteka POSIX . Chociaż ta biblioteka spełniła swoje zadanie, brak zestawu funkcji dostępnych w standardowym języku spowodował poważne problemy z przenośnością. C++ 11 pozbył się tego wszystkiego i dał nam std::wątek . Klasy wątków i powiązane funkcje są zdefiniowane w pliku plik nagłówkowy.



Składnia:

std::thread thread_object (callable);>

std::wątek to klasa wątku reprezentująca pojedynczy wątek w C++. Aby rozpocząć wątek, wystarczy utworzyć nowy obiekt wątku i przekazać kod wykonawczy (tj. obiekt wywoływalny) do konstruktora obiektu. Po utworzeniu obiektu uruchamiany jest nowy wątek, który wykona kod określony w wywołaniu. Obiekt wywoływalny może być dowolnym z pięciu:

  • Wskaźnik funkcji
  • Wyrażenie lambda
  • Obiekt funkcyjny
  • Niestatyczna funkcja członu
  • Statyczna funkcja członu

Po zdefiniowaniu wywołania przekazujemy go konstruktorowi.



Uruchamianie wątku za pomocą wskaźnika funkcji

Wskaźnik funkcji może być obiektem wywoływalnym, który można przekazać do konstruktora std::thread w celu zainicjowania wątku. Poniższy fragment kodu demonstruje, jak to się robi.

Przykład:

C++






void> foo(param)> {> >Statements;> }> // The parameters to the function are put after the comma> std::>thread> thread_obj(foo, params);>

>

>

Uruchamianie wątku przy użyciu wyrażenia Lambda

Obiekt std::thread można także uruchomić przy użyciu wyrażenia lambda jako obiektu wywoływalnego. Poniższy fragment kodu demonstruje, jak to się robi:

Przykład:

C++




// Define a lambda expression> auto> f = [](params)> {> >Statements;> };> // Pass f and its parameters to thread> // object constructor as> std::>thread> thread_object(f, params);>

>

tablica obiektów w Javie

>

Uruchamianie wątku przy użyciu obiektów funkcyjnych

Obiekty funkcyjne lub funktory mogą być również używane do uruchamiania wątku w C++. Poniższy fragment kodu demonstruje, jak to się robi:

Przykład:

C++




// Define the class of function object> class> fn_object_class {> >// Overload () operator> >void> operator()(params)> >{> >Statements;> >}> }> // Create thread object> std::>thread> thread_object(fn_object_class(), params)>

pełna forma ide

>

>

Notatka : Zawsze przekazujemy parametry wywoływalnego oddzielnie jako argumenty do konstruktora wątku.

Uruchamianie wątku przy użyciu niestatycznej funkcji członkowskiej

Możemy także uruchomić wątek za pomocą niestatycznej funkcji członkowskiej klasy. Poniższy fragment pokazuje, jak to zrobić.

C++




// defining clasc> class> Base {> public>:> >// non-static member function> >void> foo(param) { Statements; }> }> // object of Base Class> Base b;> // first parameter is the reference to the functionn> // and second paramter is reference of the object> // at last we have arguments> std::>thread> thread_obj(&Base::foo, &b, params);>

>

>

Uruchamianie wątku przy użyciu statycznej funkcji członkowskiej

Możemy także uruchamiać wątki za pomocą statycznych funkcji składowych.

C++




// defining class> class> Base {> public>:> >// static member function> >static> void> foo(param) { Statements; }> }> // object of Base Class> Base b;> // first parameter is the reference to the function> // and rest are arguments> std::>thread> thread_obj(&Base::foo, params);>

>

typ powrotu w Javie
>

Czekam na zakończenie wątków

Po rozpoczęciu wątku może być konieczne poczekanie na jego zakończenie, zanim będziemy mogli podjąć jakieś działania. Na przykład, jeśli przydzielimy zadanie inicjalizacji GUI aplikacji wątkowi, musimy poczekać na zakończenie wątku, aby upewnić się, że GUI zostało poprawnie załadowane.

Aby poczekać na wątek, użyj metody std::wątek::dołącz() funkcjonować. Ta funkcja powoduje, że bieżący wątek czeka, aż wątek zostanie zidentyfikowany przez *Ten zakończył wykonywanie.
Na przykład, aby zablokować główny wątek do czasu zakończenia wątku t1, wykonalibyśmy:

C++




int> main()> {> >// Start thread t1> >std::>thread> t1(callable);> >// Wait for t1 to finish> >t1.join();> >// t1 has finished do other stuff> >Statements;> }>

co to jest 10 na 100
>

>

Kompletny program C++ do wielowątkowości

Poniżej znajduje się program w C++. Uruchamia trzy wątki z funkcji głównej. Każdy wątek jest wywoływany przy użyciu jednego z wywoływalnych obiektów określonych powyżej.

C++




// C++ program to demonstrate> // multithreading using three> // different callables.> #include> #include> using> namespace> std;> // A dummy function> void> foo(>int> Z)> {> >for> (>int> i = 0; i cout << 'Thread using function' ' pointer as callable '; } } // A callable object class thread_obj { public: void operator()(int x) { for (int i = 0; i cout << 'Thread using function' ' object as callable '; } }; // class definition class Base { public: // non-static member function void foo() { cout << 'Thread using non-static member function ' 'as callable' << endl; } // static member function static void foo1() { cout << 'Thread using static member function as ' 'callable' << endl; } }; // Driver code int main() { cout << 'Threads 1 and 2 and 3 ' 'operating independently' << endl; // This thread is launched by using // function pointer as callable thread th1(foo, 3); // This thread is launched by using // function object as callable thread th2(thread_obj(), 3); // Define a Lambda Expression auto f = [](int x) { for (int i = 0; i cout << 'Thread using lambda' ' expression as callable '; }; // This thread is launched by using // lambda expression as callable thread th3(f, 3); // object of Base Class Base b; thread th4(&Base::foo, &b); thread th5(&Base::foo1); // Wait for the threads to finish // Wait for thread t1 to finish th1.join(); // Wait for thread t2 to finish th2.join(); // Wait for thread t3 to finish th3.join(); // Wait for thread t4 to finish th4.join(); // Wait for thread t5 to finish th5.join(); return 0; }>

>

>

Wyjście (zależne od maszyny)

Threads 1 and 2 and 3 operating independently Thread using function pointer as callable Thread using function pointer as callable Thread using function pointer as callable Thread using non-static member function as callable Thread using function object as callable Thread using function object as callable Thread using function object as callable Thread using lambda expression as callable Thread using lambda expression as callable Thread using lambda expression as callable Thread using static member function as callable>

Notatka: Aby skompilować programy z obsługą std::thread, użyj g++ -std=c++11 -pthread.