Namespaces
Variants

std:: stop_callback

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
(C++20)
stop_callback
(C++20)
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
Определено в заголовочном файле <stop_token>
template < class Callback >
class stop_callback ;
(начиная с C++20)

Класс-шаблон stop_callback предоставляет объект типа RAII, который регистрирует функцию обратного вызова для связанного std::stop_token объекта, таким образом, что функция обратного вызова будет вызвана, когда связанный std::stop_token 's std::stop_source получит запрос на остановку.

Функции обратного вызова, зарегистрированные через конструктор stop_callback , вызываются либо в том же потоке, который успешно вызывает request_stop ( ) для std::stop_source ассоциированного std::stop_token ; или если остановка уже была запрошена до регистрации конструктора, то обратный вызов вызывается в потоке, конструирующем stop_callback .

Более одного stop_callback может быть создано для одного и того же std::stop_token , из одного или разных потоков параллельно. Не предоставляется гарантий относительно порядка их выполнения, но они будут вызываться синхронно; за исключением stop_callback , созданных после того, как для std::stop_token уже был запрошен останов, как описано ранее.

Если вызов колбэка завершается через исключение, то вызывается std::terminate .

std::stop_callback не является CopyConstructible , CopyAssignable , MoveConstructible , ни MoveAssignable .

Параметр шаблона Callback должен быть одновременно invocable и destructible . Любое возвращаемое значение игнорируется.

Содержание

Типы членов

Тип Определение
callback_type Callback

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

создает новый объект stop_callback
(публичная функция-член)
уничтожает объект stop_callback
(публичная функция-член)
operator=
[deleted]
stop_callback не подлежит присваиванию
(публичная функция-член)

Руководства по выводу

Пример

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <sstream>
#include <thread>
using namespace std::chrono_literals;
// Использование вспомогательного класса для атомарного вывода в std::cout.
class Writer
{
    std::ostringstream buffer;
public:
    ~Writer()
    {
        std::cout << buffer.str();
    }
    Writer& operator<<(auto input)
    {
        buffer << input;
        return *this;
    }
};
int main()
{
    // Рабочий поток.
    // Будет ожидать, пока не поступит запрос на остановку.
    std::jthread worker([] (std::stop_token stoken)
    {
        Writer() << "Worker thread's id: " << std::this_thread::get_id() << '\n';
        std::mutex mutex;
        std::unique_lock lock(mutex);
        std::condition_variable_any().wait(lock, stoken,
            [&stoken] { return stoken.stop_requested(); });
    });
    // Регистрация стоп-коллбэка на рабочем потоке.
    std::stop_callback callback(worker.get_stop_token(), []
    {
        Writer() << "Stop callback executed by thread: "
            << std::this_thread::get_id() << '\n';
    });
    // Объекты stop_callback могут быть уничтожены досрочно для предотвращения выполнения.
    {
        std::stop_callback scoped_callback(worker.get_stop_token(), []
        {
            // Это не будет выполнено.
            Writer() << "Scoped stop callback executed by thread: "
                << std::this_thread::get_id() << '\n';
        });
    }
    // Демонстрация того, какой поток выполняет stop_callback и когда.
    // Определение функции остановки.
    auto stopper_func = [&worker]
    {
        if (worker.request_stop())
            Writer() << "Stop request executed by thread: "
                << std::this_thread::get_id() << '\n';
        else
            Writer() << "Stop request not executed by thread: "
                << std::this_thread::get_id() << '\n';
    };
    // Пусть несколько потоков соревнуются за остановку рабочего потока.
    std::jthread stopper1(stopper_func);
    std::jthread stopper2(stopper_func);
    stopper1.join();
    stopper2.join();
    // После того как остановка уже была запрошена,
    // новый stop_callback выполняется немедленно.
    Writer() << "Main thread: " << std::this_thread::get_id() << '\n';
    std::stop_callback callback_after_stop(worker.get_stop_token(), []
    {
        Writer() << "Stop callback executed by thread: "
            << std::this_thread::get_id() << '\n';
    });
}

Возможный вывод:

Worker thread's id: 140460265039616
Stop callback executed by thread: 140460256646912
Stop request executed by thread: 140460256646912
Stop request not executed by thread: 140460248254208
Main thread: 140460265043776
Stop callback executed by thread: 140460265043776