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

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

Конвейеризация данных — это общий шаблон в параллельном программировании. Конвейер данных состоит из ряда этапов, каждый из которых выполняет работу и передает результаты этой работы на следующий этап. Класс 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 в качестве входных данных и выдает на выходе квадратный корень из этого значения (значение double).

Примечание

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

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

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

cl.exe /EHsc data-pipeline.cpp

См. также

Основные понятия

Библиотека асинхронных агентов

Асинхронные блоки сообщений

Другие ресурсы

Пошаговое руководство. Создание сети обработки изображений