|
|
Defined in header <stop_token> | ||
template<class Callback> class stop_callback; | (since C++20) | |
Thestop_callback
class template provides an RAII object type that registers a callback function for an associatedstd::stop_token object, such that the callback function will be invoked when thestd::stop_token's associatedstd::stop_source is requested to stop.
Callback functions registered viastop_callback
's constructor are invoked either in the same thread that successfully invokesrequest_stop() for astd::stop_source of thestop_callback
's associatedstd::stop_token; or if stop has already been requested prior to the constructor's registration, then the callback is invoked in the thread constructing thestop_callback
.
More than onestop_callback
can be created for the samestd::stop_token, from the same or different threads concurrently. No guarantee is provided for the order in which they will be executed, but they will be invoked synchronously; except forstop_callback
(s) constructed after stop has already been requested for thestd::stop_token, as described previously.
If an invocation of a callback exits via an exception thenstd::terminate is called.
std::stop_callback
is notCopyConstructible,CopyAssignable,MoveConstructible, norMoveAssignable.
The template paramCallback
type must be bothinvocable
anddestructible
. Any return value is ignored.
Contents |
Type | Definition |
callback_type | Callback |
constructs newstop_callback object(public member function)[edit] | |
destructs thestop_callback object(public member function)[edit] | |
operator= [deleted] | stop_callback is not assignable(public member function)[edit] |
#include <chrono>#include <condition_variable>#include <iostream>#include <mutex>#include <sstream>#include <thread> usingnamespace std::chrono_literals; // Use a helper class for atomic std::cout streaming.class Writer{std::ostringstream buffer;public: ~Writer(){std::cout<< buffer.str();} Writer& operator<<(auto input){ buffer<< input;return*this;}}; int main(){// A worker thread.// It will wait until it is requested to stop.std::jthread worker([](std::stop_token stoken){ Writer()<<"Worker thread's id: "<<std::this_thread::get_id()<<'\n';std::mutex mutex;std::unique_lock lock(mutex);std::condition_variable_any().wait(lock, stoken,[&stoken]{return stoken.stop_requested();});}); // Register a stop callback on the worker thread. std::stop_callback callback(worker.get_stop_token(),[]{ Writer()<<"Stop callback executed by thread: "<<std::this_thread::get_id()<<'\n';}); // Stop_callback objects can be destroyed prematurely to prevent execution.{ std::stop_callback scoped_callback(worker.get_stop_token(),[]{// This will not be executed. Writer()<<"Scoped stop callback executed by thread: "<<std::this_thread::get_id()<<'\n';});} // Demonstrate which thread executes the stop_callback and when.// Define a stopper function.auto stopper_func=[&worker]{if(worker.request_stop()) Writer()<<"Stop request executed by thread: "<<std::this_thread::get_id()<<'\n';else Writer()<<"Stop request not executed by thread: "<<std::this_thread::get_id()<<'\n';}; // Let multiple threads compete for stopping the worker thread.std::jthread stopper1(stopper_func);std::jthread stopper2(stopper_func); stopper1.join(); stopper2.join(); // After a stop has already been requested,// a new stop_callback executes immediately. Writer()<<"Main thread: "<<std::this_thread::get_id()<<'\n'; std::stop_callback callback_after_stop(worker.get_stop_token(),[]{ Writer()<<"Stop callback executed by thread: "<<std::this_thread::get_id()<<'\n';});}
Possible output:
Worker thread's id: 140460265039616Stop callback executed by thread: 140460256646912Stop request executed by thread: 140460256646912Stop request not executed by thread: 140460248254208Main thread: 140460265043776Stop callback executed by thread: 140460265043776