Freigeben über


Gewusst wie: Verwenden von transformer in einer Datenpipeline

Dieses Thema enthält ein grundlegendes Beispiel dafür, wie die Concurrency::transformer-Klasse in einer Datenpipeline verwendet wird. Ein ausführlicheres Beispiel, in dem die Bildverarbeitung mit einer Datenpipeline erfolgt, finden Sie unter Exemplarische Vorgehensweise: Erstellen eines Bildverarbeitungsnetzwerks.

Bei Datenpipelinefunktionen handelt es sich um ein Muster, das häufig bei der gleichzeitigen Programmierung eingesetzt wird. 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 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.

Tipp

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, und fügen Sie ihn in ein Visual Studio-Projekt ein. Alternativ dazu können Sie ihn auch in eine Datei mit dem Namen data-pipeline.cpp einfügen und dann folgenden Befehl in einem Visual Studio 2010-Eingabeaufforderungsfenster ausführen.

cl.exe /EHsc data-pipeline.cpp

Siehe auch

Konzepte

Asynchronous Agents Library

Asynchrone Nachrichtenblöcke

Weitere Ressourcen

Exemplarische Vorgehensweise: Erstellen eines Bildverarbeitungsnetzwerks