std::thread Class
-
Implemented using RAII
- Similar to
std::unique_ptr,std::fstream, etc - The constructor acquires a resource
- The destructor releases the resource
- Similar to
-
An
std::threadobject has ownership of an execution thread- Only one object can be bound to an execution thread at a time
std::thread and Move Semantics
-
Move-only class
std::threadobjects cannot be copied
-
Move operations
- Transfer ownership of the execution thread
- The moved-from object is no longer associated with an execution thread
Passing a std::thread Object
- Must use pass by move
// Function taking a thread object as argument
void func(std::thread thr);
// Pass a named object
// Use std::move() to cast it to rvalue
std::thread thr(...);
func(std::move(thr));
// Pass a temporary object
func(std::thread(...));
- Moving a thread
#include <iostream>
#include <thread>
using namespace std::literals;
void hello() {
std::this_thread::sleep_for(2s);
std::cout << "hello, thread!\n";
}
// caller must provide an rvalue
void func(std::thread &&thr) {
std::cout << "Recieved thread with ID " << thr.get_id() << std::endl;
// the function argument now "owns" the system thread
// it is responsible for calling join()
thr.join();
}
int main() {
std::cout << "Starting thread...\n";
// std::thread is a move only object
std::thread thr(hello);
func(std::move(thr));
}
Returning a std::thread Object
- The compiler will automatically move it for us
// Function returning a std::thread object
std::thread func() {
// Return a local variable
std::thread thr(...);
return thr;
// Return a temporary object
return std::thread(...);
}
// The caller must use .join();
Threads and Exceptions
-
Each thread has its own execution stack
-
The stack is "unwound" when the thread throws an exception
- The destructors for all objects in scope are called
- The program moves up the thread's stack until it finds a suitable handler
- If no handler is found, the program is terminated
-
Other threads in the program cannot catch the exception
- Including the parent thread and the main thread
-
Exceptions can only be handled in the thread where they occur
- Use a try/catch block in the normal way
#include <exception>
#include <iostream>
#include <thread>
void hello() {
try {
throw std::exception();
} catch (std::exception &e) {
std::cout << "exception caught: " << e.what() << '\n';
}
std::cout << "Hello, Thread!\n";
}
int main() {
std::thread thr(hello);
thr.join();
std::cout << "Finished\n";
}