Практическое руководство. Использование преобразователя в конвейере данных
В этом разделе содержится базовый пример использования класса параллелизма::преобразователя в конвейере данных. Более полный пример, использующий конвейер данных для обработки изображений, см. в пошаговом руководстве по созданию сети обработки изображений.
Канализация данных — это распространенный шаблон в параллельном программировании. Конвейер данных состоит из ряда этапов, где каждый этап выполняет работу, а затем передает результат этой работы на следующий этап. Класс transformer
ключевого компонента в конвейерах данных, так как он получает входное значение, выполняет работу с этим значением, а затем создает результат для использования другого компонента.
Пример
В этом примере используется следующий конвейер данных для выполнения ряда преобразований с начальным входным значением:
Первый этап вычисляет абсолютное значение входных данных.
Второй этап вычисляет квадратный корень входных данных.
Третий этап вычисляет квадрат входных данных.
Четвертый этап отрицает входные данные.
Пятый этап записывает окончательный результат в буфер сообщений.
Наконец, в примере выводится результат конвейера в консоль.
// 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
См. также
Библиотека асинхронных агентов
Асинхронные блоки сообщений
Пошаговое руководство. Создание сети обработки изображений