Практическое руководство. Использование преобразователя в конвейере данных

В этом разделе содержится базовый пример использования класса параллелизма::преобразователя в конвейере данных. Более полный пример, использующий конвейер данных для обработки изображений, см. в пошаговом руководстве по созданию сети обработки изображений.

Канализация данных — это распространенный шаблон в параллельном программировании. Конвейер данных состоит из ряда этапов, где каждый этап выполняет работу, а затем передает результат этой работы на следующий этап. Класс transformer ключевого компонента в конвейерах данных, так как он получает входное значение, выполняет работу с этим значением, а затем создает результат для использования другого компонента.

Пример

В этом примере используется следующий конвейер данных для выполнения ряда преобразований с начальным входным значением:

  1. Первый этап вычисляет абсолютное значение входных данных.

  2. Второй этап вычисляет квадратный корень входных данных.

  3. Третий этап вычисляет квадрат входных данных.

  4. Четвертый этап отрицает входные данные.

  5. Пятый этап записывает окончательный результат в буфер сообщений.

Наконец, в примере выводится результат конвейера в консоль.

// data-pipeline.cpp
// compile with: /EHsc
#include <agents.h>
#include <math.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
   // Computes the absolute value of its input.
   transformer<int, int> t0([](int n) {
      return abs(n);
   });

   // Computes the square root of its input.
   transformer<int, double> t1([](int n) {
      return sqrt(static_cast<double>(n));
   });

   // Computes the square its input.
   transformer<double, int> t2([](double n) {
      return static_cast<int>(n * n);
   });

   // Negates its input.
   transformer<int, int> t3([](int n) {
      return -n;
   });

   // Holds the result of the pipeline computation.
   single_assignment<int> result;

   // Link together each stage of the pipeline.
   // t0 -> t1 -> t2 -> t3 -> result
   t0.link_target(&t1);
   t1.link_target(&t2);
   t2.link_target(&t3);
   t3.link_target(&result);

   // Propagate a message through the pipeline.
   send(t0, -42);

   // Print the result to the console.
   wcout << L"The result is " << receive(result) << L'.' << endl;
}

В примере получается следующий вывод.

The result is -42.

Обычно этап в конвейере данных выводит значение, тип которого отличается от входного значения. В этом примере второй этап принимает значение типа int в качестве входных данных и создает квадратный корень этого значения (a double) в качестве выходных данных.

Примечание.

Конвейер данных в этом примере предназначен для иллюстрации. Так как каждая операция преобразования выполняет мало работы, затраты, необходимые для выполнения передачи сообщений, могут перевесить преимущества использования конвейера данных.

Компиляция кода

Скопируйте пример кода и вставьте его в проект Visual Studio или вставьте его в файл с именем data-pipeline.cpp , а затем выполните следующую команду в окне командной строки Visual Studio.

cl.exe /EHsc data-pipeline.cpp

См. также

Библиотека асинхронных агентов
Асинхронные блоки сообщений
Пошаговое руководство. Создание сети обработки изображений