- hardware_concurrency - informuje ile wątków ze wsparciem sprzętowym jest dostępnych w systemie. Jeżeli planujemy zrównoleglić naszą pracę, trzeba pamiętać, że jeden wątek jest już zajęty przez nasz program.
- get_id - metoda wołana z std::this_thread albo na obiekcie wątku. Pozwala zorientować się z jakim wątkiem mamy do czynienia. Standard nie definiuje co to będzie, ale gwarantuje, że taki obiekt (std::thread::id), może być porównywany i wyświetlany na standardowym wyjściu.
- sleep_for - pozwala uśpić wątek na pewien czas.
Konstruktor std::thread ma podobną konstrukcję do std::bind. Trzeba pamiętać, że domyślnie wszystkie przekazane zmienne są kopiowane. Gdy interesuje nas aby wątek wyliczył i zapisał jakąś wartość do zmiennej przekazanej przez referencję, należy skorzystać z std::ref (tak jak w przypadku std::bind).
#include <iostream> #include <thread> using namespace std; struct Presenter { void operator()(int& value) { cout << "Slave id: " << std::this_thread::get_id() << endl; value += 100; std::this_thread::sleep_for(std::chrono::seconds(2)); } }; int main() { cout << "Possible threads: " << std::thread::hardware_concurrency() << endl; cout << "Master id: " << std::this_thread::get_id() << endl; int value = 1; std::thread t{ Presenter(), std::ref(value) }; cout << "Child id from master: " << t.get_id() << endl; t.join(); return 0; }Wynik:
Possible threads: 4 Master id: 140557572298560 Child id from master: 140557555422976 Slave id: 140557555422976Kłopotliwe mogą okazać się wszelkie niejawne rzutowania. W przykładzie poniżej, funkcja fun() przyjmuje jako argument std::string. Wykonanie programu będzie przebiegało w ten sposób. W pierwszej kolejności do wątku przekazany zostanie wskaźnik (char const*), a następnie wykonana zostanie konwersja do std::string (już w kontekście nowego wątku). Istnieje bardzo duża szansa, że gdy konwersja się zadzieje, zmienna z głównego wątku nie będzie już istnieć, a działanie programu będzie trudne do przewidzenia. Rozwiązaniem jest wykonanie jawnego rzutowania przed przekazaniem zmiennych do std::thread.
#include <iostream> #include <string> #include <thread> using namespace std; void fun(std::string s) { cout << "Received: " << s << endl; } int main() { char buf[10]; for (int i = 0 ; i < 3; i++) { std::sprintf(buf, "%d", i); cout << "Setting: " << buf << endl; std::thread t{ fun, buf }; // std::thread t{ fun, std::string(buf) }; // OK! t.detach(); } std::sprintf(buf, "%d", 77); std::this_thread::sleep_for(std::chrono::seconds(1)); }Wynik. Jeden z wątków dokonuje konwersji z char* na std::string, gdy wątek główny zmienił już zawartość bufora na 77 (linijka 22).
Setting: 0 Setting: 1 Received: 1 Received: 2 Setting: 2 Received: 77