Skip to content

Using Threads in C++

Related
  1. Using Mutexes and Lock Guards

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.

cpp
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.

C++
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.

Appendix

RESOURCES