std::execution::scheduler
| Definiert in Header <execution> |
||
| template< class Sch > concept scheduler = |
(1) | (seit C++26) |
| Hilfstyp für Tags |
||
| struct scheduler_t {}; |
(2) | (seit C++26) |
Das Konzept scheduler wird von Typen modelliert, die Scheduler sind, d.h. leichtgewichtige Handler für Ausführungsressourcen wie Thread-Pools, die mit der C++-Ausführungsbibliothek arbeiten.
[bearbeiten] Semantische Anforderungen
Gegeben sei ein Scheduler vom Typ Sch und eine Ausführungsumgebung vom Typ Env, sodass sender_in<schedule_result_t<Sch>, Env> erfüllt ist, dann wird /*sender-in-of*/<schedule_result_t<Sch>, Env> modelliert.
Die Copy-Konstruktor-, Destruktor-, Gleichheitsvergleichs- oder Swap-Memberfunktionen des Schedulers dürfen nicht werfen.
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 darstellen.
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 die ausstehende Fertigstellung von Empfängern, die mit den von schedule zurückgegebenen Senderobjekten verbunden sind, nicht blockieren (die zugrunde liegende Ressource kann eine separate API bereitstellen, um auf die Fertigstellung übermittelter Funktions-Objekte zu warten).
[bearbeiten] Beispiele
einfache Wrapper-Klasse für std::execution::run_loop, die ständig die run_loop-Warteschlange auf einem einzigen dedizierten Thread abfragt. Demo mit einer Entwurfsreferenzimplementierung: 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
[bearbeiten] Siehe auch
| (C++26) |
bereitet einen Task-Graphen für die Ausführung auf einem gegebenen Scheduler vor (customization point object) |