Namespaces
Variants

std:: stop_callback

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
(C++20)
stop_callback
(C++20)
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
Definiert im Header <stop_token>
template < class Callback >
class stop_callback ;
(seit C++20)

Die stop_callback -Klassenvorlage bietet einen RAII-Objekttyp, der eine Callback-Funktion für ein assoziiertes std::stop_token -Objekt registriert, sodass die Callback-Funktion aufgerufen wird, wenn die std::stop_token -assoziierte std::stop_source zum Stoppen aufgefordert wird.

Über den Konstruktor von stop_callback registrierte Callback-Funktionen werden entweder im selben Thread aufgerufen, der erfolgreich request_stop ( ) für eine std::stop_source des assoziierten std::stop_token des stop_callback aufruft; oder falls Stop bereits vor der Registrierung durch den Konstruktor angefordert wurde, wird der Callback im Thread aufgerufen, der den stop_callback konstruiert.

Mehr als ein stop_callback kann für dasselbe std::stop_token erstellt werden, vom selben oder verschiedenen Threads gleichzeitig. Es gibt keine Garantie für die Reihenfolge, in der sie ausgeführt werden, aber sie werden synchron aufgerufen; mit Ausnahme von stop_callback (s), die erstellt werden, nachdem bereits ein Stop für das std::stop_token angefordert wurde, wie zuvor beschrieben.

Wenn ein Aufruf eines Callbacks über eine Exception beendet wird, dann wird std::terminate aufgerufen.

std::stop_callback ist weder CopyConstructible , CopyAssignable , MoveConstructible noch MoveAssignable .

Der Template-Parameter Callback muss sowohl invocable als auch destructible sein. Jeder Rückgabewert wird ignoriert.

Inhaltsverzeichnis

Mitgliedertypen

Typ Definition
callback_type Callback

Memberfunktionen

Konstruiert neues stop_callback Objekt
(öffentliche Elementfunktion)
Zerstört das stop_callback Objekt
(öffentliche Elementfunktion)
operator=
[deleted]
stop_callback ist nicht zuweisbar
(öffentliche Elementfunktion)

Deduktionshilfen

Beispiel

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <sstream>
#include <thread>
using namespace std::chrono_literals;
// Verwenden Sie eine Hilfsklasse für atomare std::cout-Streaming.
class Writer
{
    std::ostringstream buffer;
public:
    ~Writer()
    {
        std::cout << buffer.str();
    }
    Writer& operator<<(auto input)
    {
        buffer << input;
        return *this;
    }
};
int main()
{
    // Ein Worker-Thread.
    // Er wartet, bis er aufgefordert wird, anzuhalten.
    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(); });
    });
    // Registrieren Sie einen Stop-Callback im Worker-Thread.
    std::stop_callback callback(worker.get_stop_token(), []
    {
        Writer() << "Stop callback executed by thread: "
            << std::this_thread::get_id() << '\n';
    });
    // Stop_callback-Objekte können vorzeitig zerstört werden, um die Ausführung zu verhindern.
    {
        std::stop_callback scoped_callback(worker.get_stop_token(), []
        {
            // Dies wird nicht ausgeführt.
            Writer() << "Scoped stop callback executed by thread: "
                << std::this_thread::get_id() << '\n';
        });
    }
    // Demonstrieren Sie, welcher Thread den stop_callback ausführt und wann.
    // Definieren Sie eine Stopper-Funktion.
    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';
    };
    // Lassen Sie mehrere Threads um das Stoppen des Worker-Threads konkurrieren.
    std::jthread stopper1(stopper_func);
    std::jthread stopper2(stopper_func);
    stopper1.join();
    stopper2.join();
    // Nachdem bereits ein Stop angefordert wurde,
    // wird ein neuer stop_callback sofort ausgeführt.
    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