std::execution:: scheduler
|
Определено в заголовочном файле
<execution>
|
||
|
template
<
class
Sch
>
concept scheduler
=
|
(1) | (начиная с C++26) |
|
Вспомогательный тип-метка
|
||
|
struct
scheduler_t
{
}
;
|
(2) | (начиная с C++26) |
Концепция
scheduler
моделируется типами, которые являются
планировщиками
, то есть легковесными обработчиками ресурсов выполнения, таких как пулы потоков, которые работают с библиотекой выполнения C++.
Семантические требования
Для планировщика типа
Sch
и среды выполнения типа
Env
таких, что выполняется условие
sender_in
<
schedule_result_t
<
Sch
>
, Env
>
, тогда
/*sender-in-of*/
<
schedule_result_t
<
Sch
>
, Env
>
моделируется.
Конструктор копирования, деструктор, оператор сравнения на равенство или функции-члены обмена планировщика должны быть не генерирующими исключения.
Все эти функции-члены, а также функция
schedule
типа планировщика должны быть потокобезопасными.
Два планировщика равны только в том случае, если они представляют один и тот же ресурс выполнения.
Для заданного планировщика
sch
выражение
get_completion_scheduler
<
set_value_t
>
(
get_env
(
schedule
(
sch
)
)
)
сравнивается эквивалентно с
sch
.
Для заданного планировщика
sch
, если выражение
get_domain
(
sch
)
корректно сформировано, то выражение
get_domain
(
get_env
(
schedule
(
sch
)
)
)
также корректно сформировано и имеет тот же тип.
Деструктор планировщика не должен блокировать выполнение до завершения любых получателей, подключенных к объектам-отправителям, возвращаемым из schedule (базовый ресурс может предоставлять отдельный API для ожидания завершения отправленных функциональных объектов)
Примеры
простой враппер для std::execution::run_loop , который постоянно опрашивает очередь run_loop в отдельном выделенном потоке. Демонстрация с использованием черновой эталонной реализации: 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'; }
Вывод:
Hello world! Have an int. Back in the main thread, result is 55
Смотрите также
|
(C++26)
|
подготавливает граф задач для выполнения на заданном планировщике
(объект точки кастомизации) |