Narzędzia użytkownika

Narzędzia witryny


Pasek boczny

sk2:cpp11_threads

To jest stara wersja strony!


Wątki w C++11

Wraz ze standardem C++11 język C++ doczekał się obsługi wątków w bibliotece standardowej.
API do obsługi wątków jest identyczne z boost::thread, z wyjątkiem obsługi przerywania wątków (thread::interrupt()).

Podsumowanie:

#include <thread> // właściwy plik nagłówkowy
std::thread t; // tworzy pusty obiekt wątku.
t = thread(f); // tworzy nowy obiekt wątku w miejscu "t", niszcząc poprzedni obiekt wątku 
               // i uruchamia w nim "f"
// thread t2 = t; // kod NIEPOPRAWNY – wątków nie można kopiować
std::thread u(g, 1, 2, "z") // tworzy obiekt wątku (u), tworzy nowy wątek programu i uruchamia
                            // "g" z argumentami 1, 2 i "z"
t.join(); // czeka na zakończenie wątku
// thread * w = new thread(h); delete w; // niepoprawne – jeśli zmienna reprezentująca wątek 
                                         // ginie (''~thread::thread'') przed zakończeniem wątku,
                                         // to program jest abortowany
// Jeśli główny wątek (main) się zakończy, pozostałe są zabijane (zachowanie inne niż np. w Javie)
u.detach() // rozłącza wątek ze zmienną go reprezentującą. Można zmazać zmienną, wątek przeżyje.
std::thread(i).detach(); // tworzy nowy wątek bez deklaracji zmiennej która będzie go reprezentować.

W C++11 ustandaryzowano też zmienne lokalne dla wątku – w deklaracji zmiennej wystarczy dodać słowo kluczowe thread_local, np:

thread_local int tid = i.fetch_add(1);

Ponadto, dodano API do zamków, zmiennych warunkowych, zmiennych atomowych i futures

<functional> w C++11

Bardzo krótkie streszczenie:

passingFuncs.cpp
#include <thread>
#include <iostream>
#include <functional>
using namespace std;
using namespace std::placeholders;
 
void b(char c){ cout << c << endl;}
 
class C{
public:
	void operator()() {cout << 'C' << endl;}
	void operator()(char c) {cout << c << endl;}
} objC;
 
class E{
	const char * t_ = "ABCDEFGH";
public: 
	char f(int i){ cout << t_[i] << endl; return t_[i];}
	void g(){t_="G";}
} objE;
 
int main() {
	thread([]{cout << "A" << endl;}).join();        // lambda – http://en.cppreference.com/w/cpp/language/lambda
	thread(b, 'B').join();                          // "zwykła" funkcja
	thread(objC).join();                            // operator()
	thread(objC, 'D').join();                       // operator() z argumentami
	thread(bind(&E::f,objE,4)).join();              // funkcja na rzecz obiektu z ustalonym argumentem (currying)
	thread(bind(&E::f,objE,_1), 5).join();          // funkcja na rzecz obiektu z nieustalonym argumentem
	function<char(int)> funR(bind(&E::f,&objE,_1)); // funkcja na rzecz obiektu wołanego przez referencję
	function<char(int)> funC(bind(&E::f, objE,_1)); // funkcja na rzecz obiektu w stanie z chwili tworzenia funcC
	objE.g();                   // modyfikacja obiektu
	thread(funR, 0).join();     // wywołanie zmodyfikowanego obiektu - funcR zna obiekt przez referencję
	thread(funC, 7).join();     // wywołanie zmodyfikowanego obiektu - funcR zna obiekt przez wartość
	return 0;
}

sk2/cpp11_threads.1509308312.txt.gz · ostatnio zmienione: 2017/10/29 21:18 przez jkonczak