Using Threads in C++
Thread objects that are joinable must either by joined or detached before they are destroyed.
Managing Threads
detach
This method can be used on a thread object to detach the thread from the calling thread. Thus the spawned thread and the calling thread execute asynchronously and non-blocking. When either thread ends execution, its resources are released. A call to detach makes a thread non-joinable.
join
The calling/main thread waits for the thread being 'joined'. Until then, it blocks the execution of the calling/main thread.
Thread Arguments
The basic usage of std::thread
is to pass a function pointer as the first parameter any additional arguments needed for the function itself in the remaining fields.
void some_fn(std::string msg) {
std::cout << "some_fn says: " << msg;
}
// Option 1: Define a free function and pass it to the thread
std::thread thread1(some_fn, "hello\n");
// Option 2: Pass a lambda to the thread
std::thread thread2([](){
std::cout << "hello from lambda\n";
}
// Blocks until `thread1` and `thread2` finish execution
thread1.join();
thread2.join();
}
void some_fn(std::string msg) {
std::cout << "some_fn says: " << msg;
}
// Option 1: Define a free function and pass it to the thread
std::thread thread1(some_fn, "hello\n");
// Option 2: Pass a lambda to the thread
std::thread thread2([](){
std::cout << "hello from lambda\n";
}
// Blocks until `thread1` and `thread2` finish execution
thread1.join();
thread2.join();
}
If passing a member function pointer, then the second parameter must be a pointer to the concrete object upon which the member function is called.
class Foo {
Foo() {};
void some_fn(int a, int b) { return a + b; };
void run_thread() {
std::thread(&Foo::some_fn, this, 1, 2).detach();
}
}
// Creating a thread using a concrete object
Foo bar();
std::thread th(&Foo::some_fn, &bar, 1, 2).detach();
// Create a thread from within a class using `this`
// as the concrete object
class Foo {
Foo() {};
void some_fn(int a, int b) { return a + b; };
void run_thread() {
std::thread(&Foo::some_fn, this, 1, 2).detach();
}
}
// Creating a thread using a concrete object
Foo bar();
std::thread th(&Foo::some_fn, &bar, 1, 2).detach();
// Create a thread from within a class using `this`
// as the concrete object
If the parameters of the function being called by the thread are references then you need to pass them in by wrapping them in the std::ref
. This avoids the thread's attempt to copy-construct the supplied parameters.
Similarly, you will have to use std::move
if you plan on passing a unique pointer to a thread.