Gewusst wie: Verwenden von transformer in einer Datenpipeline

Dieses Thema enthält ein einfaches Beispiel, das zeigt, wie die Parallelitätsklasse::Transformator in einer Datenpipeline verwendet wird. Ein vollständiges Beispiel, das eine Datenpipeline zum Ausführen der Bildverarbeitung verwendet, finden Sie unter Walkthrough: Creating an Image Processing Network.

Datenpipelineing ist ein gängiges Muster bei der gleichzeitigen Programmierung. Eine Datenpipeline besteht aus einer Reihe von Phasen, wobei in jeder einzelnen Phase Arbeiten ausführt und das jeweilige Ergebnis dann an die nächste Phase weitergeleitet wird. Die transformer-Klasse ist eine Hauptkomponente in Datenpipelines, da sie einen Eingabewert empfängt, Arbeiten für diesen Wert ausführt und dann ein Ergebnis erzeugt, das von einer anderen Komponente verwendet werden kann.

Beispiel

Bei diesem Beispiel wird zur Ausführung einer Reihe von Transformationen, denen ein ursprünglicher Eingabewert zugrunde liegt, folgende Datenpipeline verwendet:

  1. In der ersten Phase wird der absolute Wert der Eingabe berechnet.

  2. In der zweiten Phase wird die Quadratwurzel der Eingabe berechnet.

  3. In der dritten Phase wird das Quadrat der Eingabe berechnet.

  4. In der vierten Phase wird die Eingabe negiert.

  5. In der fünften Phase wird das Endergebnis in einen Meldungspuffer geschrieben.

Bei diesem Beispiel wird schließlich das Ergebnis der Pipeline auf der Konsole gedruckt.

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

Dieses Beispiel erzeugt die folgende Ausgabe:

The result is -42.

Es kommt bei einer Datenpipeline häufig vor, dass bei einer Phase ein Wert ausgegeben wird, dessen Typ sich vom Eingabewert unterscheidet. Bei diesem Beispiel wird in der zweiten Phase ein Wert des int-Typs als Eingabe verwendet und die Quadratwurzel dieses Werts (ein double) als Ausgabe erzeugt.

Hinweis

Die Datenpipeline in diesem Beispiel dient zur Veranschaulichung. Da der Arbeitsmehraufwand jedes Transformationsvorgangs gering ist, kann der Mehraufwand zum Ausführen der Meldungsübergabe die Vorteile einer Datenpipeline zunichte machen.

Kompilieren des Codes

Kopieren Sie den Beispielcode, fügen Sie ihn in ein Visual Studio-Projekt ein, oder fügen Sie ihn in eine Datei ein, die benannt data-pipeline.cpp ist, und führen Sie dann den folgenden Befehl in einem Visual Studio-Eingabeaufforderungsfenster aus.

cl.exe /EHsc data-pipeline.cpp

Siehe auch

Asynchrone Agents Library
Asynchrone Nachrichtenblöcke
Exemplarische Vorgehensweise: Erstellen eines Bildverarbeitungsnetzwerks