Namespaces
Variants

std::execution:: scheduler

From cppreference.net
Definido en el encabezado <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) (desde C++26)
Tipo de etiqueta auxiliar
struct scheduler_t { } ;
(2) (desde C++26)

El concepto scheduler está modelado por tipos que son schedulers , es decir, manejadores ligeros de recursos de ejecución como grupos de hilos que funcionan con la biblioteca de ejecución de C++.

Requisitos semánticos

Dado un planificador de tipo Sch y un entorno de ejecución de tipo Env tal que sender_in < schedule_result_t < Sch > , Env > se satisface, entonces /*sender-in-of*/ < schedule_result_t < Sch > , Env > está modelado.

El constructor de copia del planificador, el destructor, la comparación de igualdad o las funciones miembro de intercambio no deben lanzar excepciones.

Todas esas funciones miembro así como la función schedule del tipo de scheduler deben ser thread-safe.

Dos planificadores son iguales solo si representan el mismo recurso de ejecución.

Para un programador dado sch , la expresión get_completion_scheduler < set_value_t > ( get_env ( schedule ( sch ) ) ) es igual a sch .

Para un programador dado sch , si la expresión get_domain ( sch ) está bien formada, entonces la expresión get_domain ( get_env ( schedule ( sch ) ) ) también está bien formada y tiene el mismo tipo.

El destructor de un scheduler no debe bloquear la finalización pendiente de cualquier receiver conectado a los objetos sender devueltos por schedule (el recurso subyacente puede proporcionar una API separada para esperar la finalización de los objetos de función enviados)

Ejemplos

envoltura simple para std::execution::run_loop que sondea constantemente la cola de run_loop en un único hilo dedicado. Demostración usando implementación de referencia preliminar: 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';
}

Salida:

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

Véase también

prepara un grafo de tareas para su ejecución en un planificador dado
(objeto de punto de personalización)