Namespaces
Variants

std::execution:: scheduler

From cppreference.net
Definiert in Header <execution>
template < class Sch >

concept scheduler =
std:: derived_from <
typename std:: remove_cvref_t < Sch > :: scheduler_concept ,
scheduler_t > &&
/*queryable*/ < Sch > &&
requires ( Sch && sch )
{
{
std :: execution :: schedule ( std:: forward < Sch > ( sch ) )
} - > std :: execution :: sender ;
{
auto (
std :: execution :: get_completion_scheduler <
std :: execution :: set_value_t > (
std :: execution :: get_env (
std :: execution :: schedule (
std:: forward < Sch > ( sch ) ) ) )
} - > std:: same_as < std:: remove_cvref_t < Sch >> ;
} &&
std:: equality_comparable < std:: remove_cvref_t < Sch >> &&
std:: copy_constructible < std:: remove_cvref_t < Sch >> ;

} ;
(1) (seit C++26)
Hilfs-Tag-Typ
struct scheduler_t { } ;
(2) (seit C++26)

Das Konzept scheduler wird durch Typen modelliert, die Scheduler sind, also leichtgewichtige Handler für Ausführungsressourcen wie Thread-Pools, die mit der C++-Ausführungsbibliothek arbeiten.

Semantische Anforderungen

Gegeben einen Scheduler vom Typ Sch und eine Ausführungsumgebung vom Typ Env derart, dass sender_in < schedule_result_t < Sch > , Env > erfüllt ist, dann wird /*sender-in-of*/ < schedule_result_t < Sch > , Env > modelliert.

Der Kopierkonstruktor, Destruktor, Gleichheitsvergleich oder Swap-Memberfunktionen des Schedulers müssen nicht-werfend sein.

Alle diese Memberfunktionen sowie die schedule -Funktion des Scheduler-Typs müssen thread-sicher sein.

Zwei Scheduler sind nur dann gleich, wenn sie dieselbe Ausführungsressource repräsentieren.

Für einen gegebenen Scheduler sch ist der Ausdruck get_completion_scheduler < set_value_t > ( get_env ( schedule ( sch ) ) ) gleich sch .

Für einen gegebenen Scheduler sch , wenn der Ausdruck get_domain ( sch ) wohlgeformt ist, dann ist der Ausdruck get_domain ( get_env ( schedule ( sch ) ) ) ebenfalls wohlgeformt und hat denselben Typ.

Der Destruktor eines Schedulers darf nicht blockieren, bis der Abschluss von Receivern aussteht, die mit den von schedule zurückgegebenen Sender-Objekten verbunden sind (die zugrunde liegende Ressource kann eine separate API bereitstellen, um auf den Abschluss übermittelter Funktionsobjekte zu warten)

Beispiele

Einfache Wrapper-Implementierung für std::execution::run_loop , die kontinuierlich die Warteschlange der run_loop in einem einzelnen dedizierten Thread abfragt. Demo unter Verwendung der Referenzimplementierungsentwurfs: https://godbolt.org/z/146fY4Y91

#include <execution>
#include <iostream>
#include <thread>
class single_thread_context
{
    std::execution::run_loop loop_{};
    std::jthread thread_;
public:
    single_thread_context()
        : thread_([this] { loop_.run(); })
    {}
    single_thread_context(single_thread_context&&) = delete;
    ~single_thread_context()
    {
        loop_.finish();
    }
    std::execution::scheduler auto get_scheduler() noexcept
    {
        return loop_.get_scheduler();
    }
};
int main()
{
    single_thread_context ctx;
    std::execution::sender auto snd =
        std::execution::schedule(ctx.get_scheduler())
        | std::execution::then([]
            {
                std::cout << "Hello world! Have an int.\n";
                return 015;
            })
        | std::execution::then([](int arg) { return arg + 42; });
    auto [i] = std::this_thread::sync_wait(snd).value();
    std::cout << "Back in the main thread, result is " << i << '\n';
}

Ausgabe:

Hello world! Have an int.
Back in the main thread, result is 55

Siehe auch

bereitet einen Task-Graphen zur Ausführung auf einem gegebenen Scheduler vor
(Customization Point Object)