Руководство по параллелизму C ++ <будущее> (1) std :: обещание

Заголовочный файл <future> содержит следующие классы и функции:

  1. Провайдеры 类 : std :: prom, std :: package_task
  2. Futures 类 : std :: future, shared_future.
  3. Функция провайдера: std :: async ()
  4. 其他 类型 : std :: future_error, std :: future_errc, std :: future_status,
    std :: launch.

Введение в класс std :: prom

Объект обещания может хранить значение определенного типа T, которое может быть прочитано будущим объектом (возможно, в другом потоке), поэтому обещания также предоставляют средства синхронизации потоков. Когда объект обещания создается, он может быть связан с общим состоянием (обычно std :: future), а значение типа T может быть сохранено в связанном общем состоянии (std :: future).
Вы можете получить будущий объект, связанный с объектом обещания, с помощью get_future.После вызова этой функции два объекта разделяют одно и то же общее состояние.

  • Объект обещания - это асинхронный провайдер, который может устанавливать значение общего состояния в определенный момент.
  • Будущий объект может возвращать значение общего состояния асинхронно или, при необходимости, блокировать вызывающего и ждать, пока флаг общего состояния станет готовым, прежде чем получить значение общего состояния.

Вот простой пример, иллюстрирующий вышеуказанные отношения:

#include <iostream>       // std::cout
#include <functional>     // std::ref
#include <thread>         // std::thread
#include <future>         // std::promise, std::future

void print_int(std::future<int>& fut) {
    
    
    int x = fut.get(); // 获取共享状态的值.
    std::cout << "value: " << x << '\n'; // 打印 value: 10.
}

int main ()
{
    
    
    std::promise<int> prom; // 生成一个 std::promise<int> 对象.
    std::future<int> fut = prom.get_future(); // 和 future 关联.
    std::thread t(print_int, std::ref(fut)); // 将 future 交给另外一个线程t.
    
    prom.set_value(10); // 设置共享状态的值, 此处和线程t保持同步.
    std::cout << "set value 10" << std::endl;
    
    t.join();
    
    return 0;
}

std :: обещание конструктора

дефолт обещать();
с распределителем обещание шаблона (allocator_arg_t aa, const Alloc & alloc);
копировать [удалено] обещание (константное обещание &) = удалить;
переехать обещание (обещание && x) noexcept;
  1. Конструктор по умолчанию инициализирует пустое общее состояние.
  2. Конструктор с настраиваемым распределителем памяти похож на конструктор по умолчанию, но использует настраиваемый распределитель для выделения общего состояния.
  3. Конструктор копирования отключен.
  4. Конструктор перемещения.

Кроме того, operator = of std :: prom не имеет семантики копирования, то есть обычные операции присваивания std :: prom отключены, а operator = имеет только семантику перемещения, поэтому объекты std :: prom запрещено копировать.

пример:

#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <future>         // std::promise, std::future

std::promise<int> prom;

void print_global_promise() {
    
    
    std::future<int> fut = prom.get_future();
    int x = fut.get();
    std::cout << "value: " << x << '\n';
}

int main()
{
    
    
    std::thread th1(print_global_promise);
    prom.set_value(10);
    th1.join();

    prom = std::promise<int>();    // prom 被move赋值为一个新的 promise 对象.

    std::thread th2 (print_global_promise);
    prom.set_value (20);
    th2.join();

    return 0;
}

std :: обещание :: get_future 介绍

Эта функция возвращает будущее, связанное с общим состоянием обещания. Возвращенный будущий объект может получить доступ к значению, установленному для общего состояния с помощью объекта обещания или объекта исключения. Только один объект будущего может быть получен из общего состояния обещания. После вызова этой функции объект обещания обычно готов в определенный момент времени (задает значение или объект исключения). Если значение или исключение не задано, объект обещания автоматически устанавливает исключение future_error (broken_promise), когда он разрушается, чтобы установить собственное состояние готовности. Get_future упоминалось в приведенном выше примере, поэтому я не буду повторять его здесь.

Введение в std :: обещание :: set_value

Установите значение общего состояния, после чего флаг общего состояния обещания становится готовым.

Введение в std :: обещание :: set_exception

Установите исключение для обещания. После этого общее состояние обещания становится готовым. Например, поток 1 получает целое число от терминала, а поток 2 печатает целое число. Если поток 1 получает нецелое число, установите исключение для обещания (failbit), поток 2 генерирует исключение в std :: future :: get.

#include <iostream>       // std::cin, std::cout, std::ios
#include <functional>     // std::ref
#include <thread>         // std::thread
#include <future>         // std::promise, std::future
#include <exception>      // std::exception, std::current_exception

void get_int(std::promise<int>& prom) {
    
    
    int x;
    std::cout << "Please, enter an integer value: ";
    std::cin.exceptions (std::ios::failbit);   // throw on failbit
    try {
    
    
        std::cin >> x;                         // sets failbit if input is not int
        prom.set_value(x);
    } catch (std::exception&) {
    
    
        prom.set_exception(std::current_exception());
    }
}

void print_int(std::future<int>& fut) {
    
    
    try {
    
    
        int x = fut.get();
        std::cout << "value: " << x << '\n';
    } catch (std::exception& e) {
    
    
        std::cout << "[exception caught: " << e.what() << "]\n";
    }
}

int main ()
{
    
    
    std::promise<int> prom;
    std::future<int> fut = prom.get_future();

//    std::thread th1(get_int, std::ref(prom));
    std::thread th2(print_int, std::ref(fut));
    std::thread th1(get_int, std::ref(prom));

    th1.join();
    th2.join();
    
    return 0;
}

std :: обещание :: set_value_at_thread_exit 介绍

Установите значение общего состояния, но не устанавливайте флаг общего состояния в состояние готовности, объект обещания будет автоматически установлен в состояние готовности при выходе из потока. Если объект std :: future связан с общим состоянием объекта обещания, и future вызывает get, поток, вызывающий get, будет заблокирован. Когда поток завершится, поток, вызывающий future :: get, будет разблокирован, и в то же время get возвращает значение, установленное set_value_at_thread_exit. Обратите внимание, что эта функция уже установила значение общего состояния обещания. Если есть другие операции для установки или изменения значения общего состояния до завершения потока, будет выброшено future_error (обещание_already_satisfied).

Введение в std :: prom :: swap

Обменяйтесь общим состоянием обещаний.

рекомендация

отblog.csdn.net/qq_24649627/article/details/114139029