Spec-Zone.ru › C++

std::execution::run_loop

Определён в заголовочном файле <execution>
class run_loop
{
public:
    run_loop() noexcept;
    run_loop(run_loop&&) = delete;
    ~run_loop();

    /*run-loop-scheduler*/ get_scheduler() noexcept;

    void run() noexcept;
    void finish() noexcept;
};
(начиная с C++26)

run_loop — это лёгкий ресурс выполнения, владеющий потокобезопасной очередью работ с порядком FIFO, который можно использовать как цикл событий с ручным управлением. Планировщик, полученный из run_loop, ставит работы в эту очередь, а run выполняет работы из очереди в вызывающем потоке.

Этот тип в первую очередь полезен для тестов, примеров и простого выполнения в стиле цикла событий. Сам по себе он не создаёт поток: программа определяет, какой поток вызывает run.

Функции-члены

(конструктор)
создаёт run_loop
(открытая функция-член)
(деструктор)
уничтожает run_loop
(открытая функция-член)
get_scheduler
получает планировщик, связанный с run_loop
(открытая функция-член)
run
выполняет работы из очереди в вызывающем потоке
(открытая функция-член)
finish
запрашивает завершение run_loop
(открытая функция-член)

Связанный планировщик

get_scheduler возвращает объект неуказанного типа, обозначенный здесь как /*run-loop-scheduler*/.

Планировщики, полученные из одного и того же run_loop, сравниваются как равные. Планировщики, полученные из разных объектов run_loop, сравниваются как неравные. Планировщик, полученный из run_loop, остаётся действительным только пока существует соответствующий объект run_loop.

Вызов schedule для планировщика run_loop возвращает отправителя. Отправитель завершается с set_value() после выполнения запланированной работы. Если токен остановки получателя допускает остановку, отправитель вместо этого может завершиться с set_stopped(), если остановка была запрошена до выполнения операции.

Выполнение

run_loop поддерживает внутреннее состояние (которым может быть starting, running, finishing или finished) и счётчик состояний операций, находящихся в очереди.

run можно вызвать, если цикл ещё не запущен или для него запрошено завершение. Если цикл ещё не запущен, run переводит его в состояние выполнения. Затем он снова и снова извлекает первое состояние операции из очереди и выполняет его. Если работы нет, run блокируется, пока в очередь не будет добавлена работа или цикл не будет готов к завершению. run возвращается после запроса finish и выполнения всех работ из очереди.

finish запрашивает завершение цикла. Его можно вызвать до или во время run; он пробуждает заблокированный вызов run, чтобы тот мог вернуться после опустошения очереди.

Уничтожение run_loop во время его выполнения или при наличии состояний операций в очереди вызывает std::terminate.

Примечания

Запуск состояния операции, созданного с помощью планировщика run_loop, помещает операцию в очередь. Получатель операции завершается позднее, когда поток, выполняющий run, извлекает эту операцию из очереди.

За исключением конкурентных вызовов самого run и уничтожения объекта, операции с run_loop не приводят к гонкам данных.

Пример

run_loop можно использовать как основу для простого однопоточного контекста выполнения.

#include <execution>
#include <iostream>
#include <thread>

class single_thread_context
{
    std::execution::run_loop loop_;
    std::jthread worker_;

public:
    single_thread_context()
        : worker_([this] { loop_.run(); })
    {}

    ~single_thread_context()
    {
        loop_.finish();
    }

    auto get_scheduler() noexcept
    {
        return loop_.get_scheduler();
    }
};

int main()
{
    namespace ex = std::execution;

    single_thread_context ctx;

    auto snd =
        ex::schedule(ctx.get_scheduler())
      | ex::then([] {
            std::cout << "work runs on the loop\n";
            return 42;
        });

    auto [value] = std::this_thread::sync_wait(std::move(snd)).value();
    std::cout << value << '\n';
}

Вывод:

work runs on the loop
42

См. также

execution::scheduler
(C++26)
задаёт требования, согласно которым тип является планировщиком
(концепт)
execution::schedule
(C++26)
подготавливает граф задач для выполнения с помощью заданного планировщика
(объект-точка настройки)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/execution/run_loop

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API