std::execution:: scheduler
|
Definiert in Header
<execution>
|
||
|
template
<
class
Sch
>
concept scheduler
=
|
(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
|
(C++26)
|
bereitet einen Task-Graphen zur Ausführung auf einem gegebenen Scheduler vor
(Customization Point Object) |