30 Thread support library [thread]

30.3 Threads [thread.threads]

30.3.1 Class thread [thread.thread.class]

The class thread provides a mechanism to create a new thread of execution, to join with a thread (i.e., wait for a thread to complete), and to perform other operations that manage and query the state of a thread. A thread object uniquely represents a particular thread of execution. That representation may be transferred to other thread objects in such a way that no two thread objects simultaneously represent the same thread of execution. A thread of execution is detached when no thread object represents that thread. Objects of class thread can be in a state that does not represent a thread of execution. [ Note: A thread object does not represent a thread of execution after default construction, after being moved from, or after a successful call to detach or join.  — end note ]

namespace std {
  class thread {
  public:
    // types:
    class id;
    typedef implementation-defined native_handle_type; // See [thread.req.native]

    // construct/copy/destroy:
    thread() noexcept;
    template <class F, class ...Args> explicit thread(F&& f, Args&&... args);
    ~thread();
    thread(const thread&) = delete;
    thread(thread&&) noexcept;
    thread& operator=(const thread&) = delete;
    thread& operator=(thread&&) noexcept;

    // members:
    void swap(thread&) noexcept;
    bool joinable() const noexcept;
    void join();
    void detach();
    id get_id() const noexcept;
    native_handle_type native_handle(); // See [thread.req.native]

    // static members:
    static unsigned hardware_concurrency() noexcept;
  };
}

30.3.1.1 Class thread::id [thread.thread.id]

namespace std {
  class thread::id {
  public:
      id() noexcept;
  };

  bool operator==(thread::id x, thread::id y) noexcept;
  bool operator!=(thread::id x, thread::id y) noexcept;
  bool operator<(thread::id x, thread::id y) noexcept;
  bool operator<=(thread::id x, thread::id y) noexcept;
  bool operator>(thread::id x, thread::id y) noexcept;
  bool operator>=(thread::id x, thread::id y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<< (basic_ostream<charT, traits>& out, thread::id id);

  // Hash support
  template <class T> struct hash;
  template <> struct hash<thread::id>;
}

An object of type thread::id provides a unique identifier for each thread of execution and a single distinct value for all thread objects that do not represent a thread of execution ([thread.thread.class]). Each thread of execution has an associated thread::id object that is not equal to the thread::id object of any other thread of execution and that is not equal to the thread::id object of any std::thread object that does not represent threads of execution.

thread::id shall be a trivially copyable class (Clause [class]). The library may reuse the value of a thread::id of a terminated thread that can no longer be joined.

Note: Relational operators allow thread::id objects to be used as keys in associative containers.  — end note ]

id() noexcept;

Effects: Constructs an object of type id.

Postconditions: The constructed object does not represent a thread of execution.

bool operator==(thread::id x, thread::id y) noexcept;

Returns: true only if x and y represent the same thread of execution or neither x nor y represents a thread of execution.

bool operator!=(thread::id x, thread::id y) noexcept;

Returns: !(x == y)

bool operator<(thread::id x, thread::id y) noexcept;

Returns: A value such that operator< is a total ordering as described in [alg.sorting].

bool operator<=(thread::id x, thread::id y) noexcept;

Returns: !(y < x)

bool operator>(thread::id x, thread::id y) noexcept;

Returns: y < x

bool operator>=(thread::id x, thread::id y) noexcept;

Returns: !(x < y)

template<class charT, class traits> basic_ostream<charT, traits>& operator<< (basic_ostream<charT, traits>&& out, thread::id id);

Effects: Inserts an unspecified text representation of id into out. For two objects of type thread::id x and y, if x == y the thread::id objects shall have the same text representation and if x != y the thread::id objects shall have distinct text representations.

Returns: out

template <> struct hash<thread::id>;

Requires: the template specialization shall meet the requirements of class template hash ([unord.hash]).

30.3.1.2 thread constructors [thread.thread.constr]

thread() noexcept;

Effects: Constructs a thread object that does not represent a thread of execution.

Postcondition: get_id() == id()

template <class F, class ...Args> explicit thread(F&& f, Args&&... args);

Requires: F and each Ti in Args shall satisfy the MoveConstructible requirements. INVOKE(DECAY_COPY( std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...) ([func.require]) shall be a valid expression.

Effects: Constructs an object of type thread. The new thread of execution executes INVOKE(DECAY_COPY( std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...) with the calls to DECAY_COPY being evaluated in the constructing thread. Any return value from this invocation is ignored. [ Note: This implies that any exceptions not thrown from the invocation of the copy of f will be thrown in the constructing thread, not the new thread.  — end note ] If the invocation of INVOKE(DECAY_COPY( std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...) terminates with an uncaught exception, std::terminate shall be called.

Synchronization: The completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of f.

Postconditions: get_id() != id(). *this represents the newly started thread.

Throws: system_error if unable to start the new thread.

Error conditions:

  • resource_unavailable_try_again — the system lacked the necessary resources to create another thread, or the system-imposed limit on the number of threads in a process would be exceeded.

thread(thread&& x) noexcept;

Effects: Constructs an object of type thread from x, and sets x to a default constructed state.

Postconditions: x.get_id() == id() and get_id() returns the value of x.get_id() prior to the start of construction.

30.3.1.3 thread destructor [thread.thread.destr]

~thread();

If joinable(), calls std::terminate(). Otherwise, has no effects. [ Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable.  — end note ]

30.3.1.4 thread assignment [thread.thread.assign]

thread& operator=(thread&& x) noexcept;

Effects: If joinable(), calls std::terminate(). Otherwise, assigns the state of x to *this and sets x to a default constructed state.

Postconditions: x.get_id() == id() and get_id() returns the value of x.get_id() prior to the assignment.

Returns: *this

30.3.1.5 thread members [thread.thread.member]

void swap(thread& x) noexcept;

Effects: Swaps the state of *this and x.

bool joinable() const noexcept;

Returns: get_id() != id()

void join();

Requires: joinable() is true.

Effects: Blocks until the thread represented by *this has completed.

Synchronization: The completion of the thread represented by *this synchronizes with ([intro.multithread]) the corresponding successful join() return. [ Note: Operations on *this are not synchronized.  — end note ]

Postconditions: The thread represented by *this has completed. get_id() == id().

Throws: system_error when an exception is required ([thread.req.exception]).

Error conditions:

  • resource_deadlock_would_occur — if deadlock is detected or this->get_id() == std::this_thread::get_id().

  • no_such_process — if the thread is not valid.

  • invalid_argument — if the thread is not joinable.

void detach();

Requires: joinable() is true.

Effects: The thread represented by *this continues execution without the calling thread blocking. When detach() returns, *this no longer represents the possibly continuing thread of execution. When the thread previously represented by *this ends execution, the implementation shall release any owned resources.

Postcondition: get_id() == id().

Throws: system_error when an exception is required ([thread.req.exception]).

Error conditions:

  • no_such_process — if the thread is not valid.

  • invalid_argument — if the thread is not joinable.

id get_id() const noexcept;

Returns: A default constructed id object if *this does not represent a thread, otherwise this_thread::get_id() for the thread of execution represented by *this.

30.3.1.6 thread static members [thread.thread.static]

unsigned hardware_concurrency() noexcept;

Returns: The number of hardware thread contexts. [ Note: This value should only be considered to be a hint.  — end note ] If this value is not computable or well defined an implementation should return 0.

30.3.1.7 thread specialized algorithms [thread.thread.algorithm]

void swap(thread& x, thread& y) noexcept;

Effects: x.swap(y)