[thread.jthread.class] (original) (raw)

32 Thread support library [thread]

32.4 Threads [thread.threads]

32.4.3 Class jthread [thread.jthread.class]

The class jthread provides a mechanism to create a new thread of execution.

The functionality is the same as for class thread ([thread.thread.class]) with the additional abilities to provide a stop_­token ([thread.stoptoken]) to the new thread of execution, make stop requests, and automatically join.

namespace std { class jthread { public:

using id = thread::id;
using native_handle_type = thread::native_handle_type;


jthread() noexcept;
template<class F, class... Args> explicit jthread(F&& f, Args&&... args);
~jthread();
jthread(const jthread&) = delete;
jthread(jthread&&) noexcept;
jthread& operator=(const jthread&) = delete;
jthread& operator=(jthread&&) noexcept;


void swap(jthread&) noexcept;
[[nodiscard]] bool joinable() const noexcept;
void join();
void detach();
[[nodiscard]] id get_id() const noexcept;
[[nodiscard]] native_handle_type native_handle();   


[[nodiscard]] stop_source get_stop_source() noexcept;
[[nodiscard]] stop_token get_stop_token() const noexcept;
bool request_stop() noexcept;


friend void swap(jthread& lhs, jthread& rhs) noexcept;


[[nodiscard]] static unsigned int hardware_concurrency() noexcept;

private: stop_source ssource;
}; }

32.4.3.1 Constructors, move, and assignment [thread.jthread.cons]

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

Postconditions: get_­id() == id() is trueand ssource.stop_­possible() is false.

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

Constraints: remove_­cvref_­t<F> is not the same type as jthread.

Mandates:The following are all true:

Preconditions: decay_­t<F> and each type in decay_­t<Args> meet theCpp17MoveConstructible requirements.

Effects:Initializes ssource.

The new thread of execution executes

invoke(decay-copy(std::forward(f)), get_stop_token(), decay-copy(std::forward(args))...)

if that expression is well-formed, otherwise

invoke(decay-copy(std::forward(f)), decay-copy(std::forward(args))...)

with the calls todecay-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 invoke expression exits via an exception,terminate is 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() is trueand ssource.stop_­possible() is trueand *this represents the newly started thread.

[ Note

:

The calling thread can make a stop request only once, because it cannot replace this stop token.

end note

]

Throws: system_­error if unable to start the new thread.

Error conditions:

jthread(jthread&& x) noexcept;

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

ssource has the value of x.ssourceprior to the start of construction and x.ssource.stop_­possible() is false.

Effects:If joinable() is true, calls request_­stop() and then join().

[ Note

:

Operations on *this are not synchronized.

end note

]

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

Effects:If joinable() is true, calls request_­stop() and then join().

Assigns the state of x to *thisand 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.

ssource has the value of x.ssourceprior to the assignment and x.ssource.stop_­possible() is false.

32.4.3.2 Members [thread.jthread.mem]

void swap(jthread& x) noexcept;

Effects:Exchanges the values of *this and x.

[[nodiscard]] bool joinable() const noexcept;

Returns: get_­id() != id().

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

Synchronization:The completion of the thread represented by *thissynchronizes 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().

Error conditions:

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 releases any owned resources.

Postconditions: get_­id() == id().

Error conditions:

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.

32.4.3.3 Stop token handling [thread.jthread.stop]

[[nodiscard]] stop_source get_stop_source() noexcept;

Effects:Equivalent to: return ssource;

[[nodiscard]] stop_token get_stop_token() const noexcept;

Effects:Equivalent to: return ssource.get_­token();

bool request_stop() noexcept;

Effects:Equivalent to: return ssource.request_­stop();

32.4.3.4 Specialized algorithms [thread.jthread.special]

friend void swap(jthread& x, jthread& y) noexcept;

Effects:Equivalent to: x.swap(y).

32.4.3.5 Static members [thread.jthread.static]

[[nodiscard]] static unsigned int hardware_concurrency() noexcept;

Returns: thread​::​hardware_­concurrency().