- 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