Namensräume
Varianten
Aktionen

std::stop_callback

Von cppreference.com
< cpp‎ | thread
 
 
Bibliothek für nebenläufige Programmierung
Threads
(C++11)
(C++20)
this_thread Namespace
(C++11)
(C++11)
(C++11)
Kooperatives Beenden
(C++20)
stop_callback
(C++20)
Gegenseitiger Ausschluss
(C++11)
Allgemeines Sperrungsmanagement
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Bedingungsvariablen
(C++11)
Semaphoren
Latches und Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
(C++11)
Sichere Wiederherstellung
(C++26)
Hazard Pointer
Atomare Typen
(C++11)
(C++20)
Initialisierung von atomaren Typen
(C++11)(veraltet in C++20)
(C++11)(veraltet in C++20)
Speicherordnung
(C++11)(deprecated in C++26)
Freie Funktionen für atomare Operationen
Freie Funktionen für atomare Flags
 
 
Definiert in Header <stop_token>
template< class Callback >
class stop_callback;
(seit C++20)

Die Klassen-Template stop_callback stellt einen RAII-Objekttyp bereit, der eine Callback-Funktion für ein assoziiertes std::stop_token-Objekt registriert, sodass die Callback-Funktion aufgerufen wird, wenn die std::stop_source des zugehörigen std::stop_token aufgefordert wird, zu stoppen.

Callback-Funktionen, die über den Konstruktor von stop_callback registriert werden, werden entweder im selben Thread aufgerufen, der erfolgreich request_stop() für eine std::stop_source des zugehörigen std::stop_token aufruft; oder, wenn das Stoppen bereits vor der Registrierung im Konstruktor angefordert wurde, wird der Callback im Thread aufgerufen, der stop_callback konstruiert.

Mehrere stop_callback-Objekte können für dasselbe std::stop_token, aus demselben oder unterschiedlichen Threads gleichzeitig erstellt werden. Es gibt keine Garantie für die Reihenfolge, in der sie ausgeführt werden, aber sie werden synchron aufgerufen; außer für stop_callback(s), die konstruiert werden, nachdem das Stoppen für das std::stop_token bereits angefordert wurde, wie zuvor beschrieben.

Wenn ein Aufruf eines Callbacks aufgrund einer Ausnahme beendet wird, wird std::terminate aufgerufen.

std::stop_callback ist nicht CopyConstructible, CopyAssignable, MoveConstructible oder MoveAssignable.

Der Template-Parameter Callback muss sowohl invocable als auch destructible sein. Rückgabewerte werden ignoriert.

Inhalt

[edit] Member types

Typ Definition
callback_type Callback

[edit] Member functions

konstruiert ein neues stop_callback-Objekt
(public member function) [edit]
destruiert das stop_callback-Objekt
(public member function) [edit]
operator=
[gelöscht]
stop_callback ist nicht zuweisbar
(public member function) [edit]

[edit] Deduction guides

[edit] Example

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <sstream>
#include <thread>
 
using namespace 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';
    });
}

Mögliche Ausgabe

Worker thread's id: 140460265039616
Stop callback executed by thread: 140460256646912
Stop request executed by thread: 140460256646912
Stop request not executed by thread: 140460248254208
Main thread: 140460265043776
Stop callback executed by thread: 140460265043776