Mastering std::thread: Create, Manage, and Synchronize C++ Threads
This tutorial explains the fundamentals of C++11 std::thread, covering thread creation with functions and lambdas, the use of join() and detach(), argument passing techniques, and essential best practices for safe and portable multithreaded programming.
In modern computer systems, multi‑core processors are mainstream. To fully utilize hardware resources, writing concurrent programs is essential. Before C++11, multithreading required OS‑specific APIs, which were cumbersome and non‑portable. C++11 introduced the <thread> header, providing the std::thread class for powerful and portable multithreading support. This section explores the basics of std::thread to help you start C++ concurrent programming.
1. What is std::thread?
std::threadis a class representing a single execution thread. Each std::thread object represents an independent thread. You can create multiple std::thread objects to run several functions concurrently.
2. Creating your first thread
Creating a new thread is simple: construct a std::thread object and pass the callable (function, functor, lambda, etc.) you want to run in the new thread as an argument.
Example 1: Using a function
#include <iostream>
#include <thread>
// This function will be executed in a new thread
void helloFunction()
{
std::cout << "Hello from thread (function)!
";
}
int main()
{
// Create a new thread t and immediately execute helloFunction
std::thread t(helloFunction);
// Main thread continues its work
std::cout << "Hello from main thread!
";
// Wait for thread t to finish
t.join();
return 0;
}Possible output:
Hello from main thread!
Hello from thread (function)!Or
Hello from thread (function)!
Hello from main thread!Note: The output order is nondeterministic because it depends on the OS scheduler, illustrating thread concurrency.
Example 2: Using a lambda expression (more modern)
#include <iostream>
#include <thread>
int main()
{
// Create thread using a lambda
std::thread t([](){
std::cout << "Hello from thread (lambda)!
";
});
std::cout << "Hello from main thread!
";
t.join();
return 0;
}3. Waiting for a thread to finish: join()
join()is a key member function of std::thread. It blocks the current thread (usually the main thread) until the called thread ( t) completes. In the examples above, t.join() blocks main until helloFunction or the lambda finishes.
Why must you call join()?
The C++ standard mandates that if a std::thread object is still joinable (created but not joined or detached) when it is destroyed, std::terminate() is invoked, terminating the program. Therefore you must call join() or detach() before the thread object's lifetime ends.
4. Letting a thread run independently: detach()
Unlike join(), detach() separates the thread. After calling detach():
The main thread and the child thread are completely independent.
The child becomes a daemon thread running in the background.
The main thread can no longer interact with the std::thread object.
When the child finishes, its resources are reclaimed automatically.
Example:
#include <iostream>
#include <thread>
#include <chrono>
void independentWorker()
{
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "Worker thread done after sleeping.
";
}
int main()
{
std::thread t(independentWorker);
t.detach(); // Let the thread run on its own
std::cout << "Main thread is done. Exiting.
";
// Note: The background thread may still be running after main exits.
std::this_thread::sleep_for(std::chrono::seconds(3)); // Wait to see output
return 0;
}Using detach() requires extreme care because you lose direct control over the thread and must ensure any data accessed by the thread remains valid for its lifetime.
5. Passing arguments to thread functions
Passing arguments to a thread function works like a normal function call: list the arguments after the callable.
Example:
#include <iostream>
#include <thread>
#include <string>
void printMessage(const std::string& msg, int id)
{
std::cout << "Thread " << id << ": " << msg << '
';
}
void increment(int& x)
{
++x;
}
int main()
{
std::string message = "Hello, World!";
int threadId = 1;
// 1. Pass by value (default)
std::thread t1(printMessage, message, threadId);
t1.join();
int value = 10;
// 2. Pass by reference using std::ref
std::thread t2(increment, std::ref(value));
t2.join();
std::cout << "Value after increment: " << value << '
';
// 3. Move-only types using std::move
std::unique_ptr<int> ptr(new int(42));
std::thread t3([](std::unique_ptr<int> p){
std::cout << "Value in thread: " << *p << '
';
}, std::move(ptr));
t3.join(); // ptr is now empty in the main thread
return 0;
}Key points:
Default is value copy, giving each thread its own data copy.
To pass a reference, wrap the argument with std::ref() or std::cref().
To pass move‑only types, use std::move() to transfer ownership.
6. Core takeaways and best practices
RAII for threads: always call join() or detach() before a std::thread object is destroyed; consider a wrapper class to automate this.
Prefer join() over detach() unless you have a strong reason; it gives better control over thread lifetime.
Beware data races: protect shared data with synchronization primitives such as std::mutex (to be covered later).
Threads are non‑copyable; they can only be moved with std::move, reflecting exclusive ownership of thread resources.
Conclusion
std::threadis the cornerstone of C++ multithreading. After this section you should understand how to create threads with functions and lambdas, the differences and usage of join() and detach(), how to pass arguments (by value, reference, or move), and basic best practices and cautions.
Future sections will explore stronger synchronization primitives such as std::mutex, std::atomic, and advanced thread‑management techniques to help you build robust and efficient multithreaded C++ applications.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
php Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
