C++20 Concurrency: std::jthread

This new threading mechanism will greatly improve your existing code

CMP
2 min readJun 6

--

C++20 has introduced several new features to help developers write simpler, safer, and more efficient concurrent code. One of these features is the std::jthread mechanism.

What is it?

std::jthread is a new concurrency mechanism in C++20 that represents a joinable thread (hence the “j” in “jthread”) with automatic cleanup. std::jthread also incorporates some of the other new C++20 concurrency features, such as std::stop_token, but this is a topic for another discussion.

If you’ve written concurrent code in the past with C++, then you are likely familiar with std::thread. Here is a simple example:

void printSomething(const std::string& message) {
std::cout << "Thread ID: " << std::this_thread::get_id() << " Message: " << message << std::endl;
}

int main() {
std::cout << "Starting Thread 1..." << std::endl;
std::thread thread1(printSomething, "Thread 1 says hello!");

std::cout << "Starting Thread 2..." << std::endl;
std::thread thread2(printSomething, "Thread 2 says hello!");

std::cout << "Waiting for threads to finish..." << std::endl;
thread1.join();
thread2.join();

return 0;
}

By calling .join() on a thread, you are ensuring that the thread will finish its execution before continuing with the execution of the calling thread (the main thread in this case). If you don’t call .join() (or .detach()), then the destructor of std::thread will terminate the whole program! This leads to many bugs…

In C++20, you can eliminate these bugs, as well as the explicit calls to .join(), by using std::jthread:

void printSomething(const std::string& message) {
std::cout << "Thread ID: " << std::this_thread::get_id() << " Message: " << message << std::endl;
}

int main() {
std::cout << "Starting Thread 1..." << std::endl;
std::jthread thread1(printSomething, "Thread 1 says hello!");

std::cout << "Starting Thread 2..." << std::endl;
std::jthread thread2(printSomething, "Thread 2 says hello!");

return 0;
}

std::jthread joins the thread on destruction, so when the thread goes out of scope, it is automatically joined! The std::jthread object has ownership of the thread’s execution and is responsible for managing the lifetime and resources of the thread. If you are writing code that follows the Resource Acquisition Is Initialization (RAII) paradigm (which you should), then you should incorporate std::jthread.

--

--