liveBook · Manning

Std::thread

As explained in C++ Concurrency in Action, Second Edition

A C++ standard library class that represents and manages a thread of execution.

`std::thread` is the C++ Standard Library object used to start and manage a thread of execution. Include `<thread>`, then construct a `std::thread` with the function the new thread should run. The constructing thread continues independently; the new thread stops when its function returns. section 2.1.1 section 2.1

Listing 1.1. A simple Hello Concurrent World program
#include <iostream>
#include <thread>
void hello()
{
    std::cout<<"Hello Concurrent World\n";
}
int main()
{
    std::thread t(hello);   3
    t.join();
}

The `hello` function runs on the new thread, while `main` calls `join()` to wait for it. Without that wait, `main` could end before the message is printed. section 1.4.1

The constructor accepts other callable types too. A function object is copied into the new thread’s storage before invocation, so its copy must behave as intended. A lambda can also supply the work. Beware `std::thread my_thread(background_task());`: it can be parsed as a function declaration, not a thread launch. Use a named function object or brace initialization instead. section 2.1.1

A detached thread outlives its local reference

A function object holds a reference to a local variable, and its `std::thread` is detached. The creating function can return and destroy that variable while the new thread still uses the reference, causing undefined behavior. Plan the lifetime of anything a thread accesses. section 2.1.1

A `std::thread` owns its association with a thread of execution, but that ownership is movable, not copyable. `std::move` transfers it from a named object; afterward, the old object has no associated thread. Moving into an object that already owns a thread calls `std::terminate()`. Threads can therefore be returned from functions, passed to other functions, or kept in a `std::vector`; a wrapper can also join its thread when the wrapper is destroyed. section 2.3

Listing 2.8. Spawns some threads and waits for them to finish
void do_work(unsigned id);
void f()
{
    std::vector<std::thread> threads;
    for(unsigned i=0;i<20;++i)
    {
        threads.emplace_back(do_work,i);     #1
    }
    for(auto& entry: threads)                #2
        entry.join();
}

The vector holds 20 thread objects created with a function and an argument. A second loop joins each one, keeping the wait separate from thread creation. section 2.3

How C++ Concurrency in Action, Second Edition covers it

How deep it goes
Works through construction, callable forms, lifetime risks, moves, and joining patterns without detailing thread-scheduling internals.
Examples
Uses a greeting thread, a detached thread with a dangling reference, ownership transfers, and a vector of worker threads.
What it assumes
Starts with an ordinary C++ function and introduces thread launching without assuming prior concurrency experience.
What you can do after
Apply it via the C++ Standard Library to launch threads, join them, and transfer their ownership without losing track of lifetime risks.
How it connects
Connects callable objects and lambdas to join, detach, move semantics, and resource-owning wrappers.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of C++ Concurrency in Action, Second Edition. The section links point to the parts of the book it draws on.