Porady: używanie transformatora w potoku danych

Ten temat zawiera podstawowy przykład pokazujący, jak używać klasy concurrency::transformer w potoku danych. Aby uzyskać bardziej kompletny przykład, który używa potoku danych do przetwarzania obrazów, zobacz Przewodnik: tworzenie sieci przetwarzania obrazów.

Potokowanie danych jest typowym wzorcem w programowaniu współbieżnym. Potok danych składa się z serii etapów, w których każdy etap wykonuje pracę, a następnie przekazuje wynik tej pracy do następnego etapu. Klasa transformer składnika klucza w potokach danych, ponieważ otrzymuje wartość wejściową, wykonuje pracę nad tą wartością, a następnie generuje wynik dla innego składnika do użycia.

Przykład

W tym przykładzie użyto następującego potoku danych do wykonania serii przekształceń przy użyciu początkowej wartości wejściowej:

  1. Pierwszy etap oblicza wartość bezwzględną danych wejściowych.

  2. Drugi etap oblicza pierwiastek kwadratowy danych wejściowych.

  3. Trzeci etap oblicza kwadrat danych wejściowych.

  4. Następny etap neguje swoje dane wejściowe.

  5. Piąty etap zapisuje wynik końcowy w buforze komunikatów.

Na koniec przykład wyświetla wynik potoku w konsoli programu .

// 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;
}

Ten przykład generuje następujące wyniki:

The result is -42.

Często zdarza się, że etap w potoku danych zwraca wartość, której typ różni się od jego wartości wejściowej. W tym przykładzie drugi etap przyjmuje wartość typu int jako dane wejściowe i generuje pierwiastek kwadratowy tej wartości (a double) jako dane wyjściowe.

Uwaga

Potok danych w tym przykładzie służy do ilustracji. Ponieważ każda operacja przekształcania wykonuje niewielką pracę, obciążenie wymagane do wykonania przekazywania komunikatów może przewyższać korzyści wynikające z korzystania z potoku danych.

Kompilowanie kodu

Skopiuj przykładowy kod i wklej go w projekcie programu Visual Studio lub wklej go w pliku o nazwie data-pipeline.cpp , a następnie uruchom następujące polecenie w oknie wiersza polecenia programu Visual Studio.

cl.exe /EHsc data-pipeline.cpp

Zobacz też

Biblioteki agentów asynchronicznych
Bloki komunikatów asynchronicznych
Przewodnik: tworzenie sieci przetwarzania obrazów