Udostępnij za pośrednictwem


Instruktaż: Wykonawczych prognoz

W tym temacie przedstawiono sposób wykonania prognoz w aplikacji.Temat demonstruje, jak połączyć istniejące funkcje w czasie wykonywania współbieżności w coś ma więcej.

Ważna uwagaWażne

W tym temacie przedstawiono pojęcia prognozy dla celów demonstracyjnych.Zaleca się używanie std::future lub concurrency::task gdy wymagają zadanie asynchroniczne, który oblicza wartość do późniejszego użycia.

A zadania jest obliczeń, który może być rozłożony na dodatkowe, bardziej szczegółowymi obliczenia.A przyszłych jest zadanie asynchroniczne, który oblicza wartość do późniejszego użycia.

Aby zaimplementować typu futures, w tym temacie opisano async_future klasy.async_future Klasy używa tych składników Runtime współbieżności: concurrency::task_group klasy i concurrency::single_assignment klasy.async_future Klasy zastosowań task_group klasy obliczyć wartość asynchronicznie i single_assignment klasy do przechowywania wyników obliczeń.Konstruktor async_future klasa wykorzystuje funkcję pracy, która oblicza wynik, oraz get metoda pobiera wynik.

Aby zaimplementować klasę async_future

  1. Stwierdzenie klasę szablon o nazwie async_future , jest parametryzowana typu Wynikowe obliczeń.Dodaj public i private sekcji do tej klasy.

    template <typename T>
    class async_future
    {
    public:
    private:
    };
    
  2. W private sekcji async_future klasy, oświadczyć, task_group i single_assignment elementu danych.

    // Executes the asynchronous work function.
    task_group _tasks;
    
    // Stores the result of the asynchronous work function.
    single_assignment<T> _value;
    
  3. W public sekcji async_future klasy, implementować konstruktora.Konstruktora jest szablon, który jest parametryzowana na funkcji pracy, która oblicza wynik.Konstruktora asynchronicznie wykonuje funkcja pracy w task_group Członkowskich danych i zastosowań concurrency::send funkcji zapisać wynik do single_assignment elementu danych.

    template <class Functor>
    explicit async_future(Functor&& fn)
    {
       // Execute the work function in a task group and send the result
       // to the single_assignment object.
       _tasks.run([fn, this]() {
          send(_value, fn());
        });
    }
    
  4. W public sekcji async_future klasy, zaimplementować destruktor.Destruktor czeka na zakończenie zadania.

    ~async_future()
    {
       // Wait for the task to finish.
       _tasks.wait();
    }
    
  5. W public sekcji async_future klasy, zaimplementować get metody.Metoda ta wykorzystuje concurrency::receive funkcji pobrać wynik funkcji pracy.

    // Retrieves the result of the work function.
    // This method blocks if the async_future object is still 
    // computing the value.
    T get()
    { 
       return receive(_value); 
    }
    

Przykład

Dd764564.collapse_all(pl-pl,VS.110).gifOpis

Poniższy przykład przedstawia kompletnego async_future klasy i przykładem jego użycia.wmain Funkcja tworzy std::vector obiektu zawierającego 10 000 wartości losową liczbę całkowitą.Następnie async_future obiektów, aby znaleźć najmniejszą i największą wartość, które są zawarte w vector obiektu.

Dd764564.collapse_all(pl-pl,VS.110).gifKod

// futures.cpp
// compile with: /EHsc
#include <ppl.h>
#include <agents.h>
#include <vector>
#include <algorithm>
#include <iostream>
#include <numeric>
#include <random>

using namespace concurrency;
using namespace std;

template <typename T>
class async_future
{
public:
   template <class Functor>
   explicit async_future(Functor&& fn)
   {
      // Execute the work function in a task group and send the result
      // to the single_assignment object.
      _tasks.run([fn, this]() {
         send(_value, fn());
       });
   }

   ~async_future()
   {
      // Wait for the task to finish.
      _tasks.wait();
   }

   // Retrieves the result of the work function.
   // This method blocks if the async_future object is still 
   // computing the value.
   T get()
   { 
      return receive(_value); 
   }

private:
   // Executes the asynchronous work function.
   task_group _tasks;

   // Stores the result of the asynchronous work function.
   single_assignment<T> _value;
};

int wmain()
{
   // Create a vector of 10000 integers, where each element 
   // is between 0 and 9999.
   mt19937 gen(2);
   vector<int> values(10000);   
   generate(begin(values), end(values), [&gen]{ return gen()%10000; });

   // Create a async_future object that finds the smallest value in the
   // vector.
   async_future<int> min_value([&]() -> int { 
      int smallest = INT_MAX;
      for_each(begin(values), end(values), [&](int value) {
         if (value < smallest)
         {
            smallest = value;
         }
      });
      return smallest;
   });

   // Create a async_future object that finds the largest value in the
   // vector.
   async_future<int> max_value([&]() -> int { 
      int largest = INT_MIN;
      for_each(begin(values), end(values), [&](int value) {
         if (value > largest)
         {
            largest = value;
         } 
      });
      return largest;
   });

   // Calculate the average value of the vector while the async_future objects
   // work in the background.
   int sum = accumulate(begin(values), end(values), 0);
   int average = sum / values.size();

   // Print the smallest, largest, and average values.
   wcout << L"smallest: " << min_value.get() << endl
         << L"largest:  " << max_value.get() << endl
         << L"average:  " << average << endl;
}

Dd764564.collapse_all(pl-pl,VS.110).gifKomentarze

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

smallest: 0
largest:  9999
average:  4981

W przykładzie użyto async_future::get metoda pobierania wyniki obliczeń.async_future::get Metoda czeka na obliczeń, aby zakończyć, jeżeli obliczeń jest wciąż aktywne.

Stabilne Programowanie

Rozszerzenie async_future klasy do obsługi wyjątków, które są generowane przez funkcję pracy, modyfikowanie async_future::get wywołania metody concurrency::task_group::wait metody.task_group::wait Metoda wygeneruje wyjątkami, które zostały wygenerowane przez funkcję pracy.

W poniższym przykładzie pokazano zmodyfikowanej wersji async_future klasy.wmain Działać zastosowań try-catch bloku do drukowania wynik async_future obiektu lub do drukowania wartości wyjątek, który jest generowany przez funkcję pracy.

// futures-with-eh.cpp
// compile with: /EHsc
#include <ppl.h>
#include <agents.h>
#include <vector>
#include <algorithm>
#include <iostream>

using namespace concurrency;
using namespace std;

template <typename T>
class async_future
{
public:
   template <class Functor>
   explicit async_future(Functor&& fn)
   {
      // Execute the work function in a task group and send the result
      // to the single_assignment object.
      _tasks.run([fn, this]() {
         send(_value, fn());
       });
   }

   ~async_future()
   {
      // Wait for the task to finish.
      _tasks.wait();
   }

   // Retrieves the result of the work function.
   // This method blocks if the async_future object is still
   // computing the value.
   T get()
   { 
      // Wait for the task to finish.
      // The wait method throws any exceptions that were generated
      // by the work function.
      _tasks.wait();

      // Return the result of the computation.
      return receive(_value);
   }

private:
   // Executes the asynchronous work function.
   task_group _tasks;

   // Stores the result of the asynchronous work function.
   single_assignment<T> _value;
};

int wmain()
{
   // For illustration, create a async_future with a work 
   // function that throws an exception.
   async_future<int> f([]() -> int { 
      throw exception("error");
   });

   // Try to read from the async_future object. 
   try
   {
      int value = f.get();
      wcout << L"f contains value: " << value << endl;
   }
   catch (const exception& e)
   {
      wcout << L"caught exception: " << e.what() << endl;
   }
}

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

caught exception: error

Aby uzyskać więcej informacji na temat modelu obsługi wyjątków w czasie wykonywania współbieżności, zobacz Obsługa wyjątków w Runtime współbieżności.

Kompilowanie kodu

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

cl.exe /EHsc futures.cpp

Zobacz też

Informacje

Klasa task_group

Klasa single_assignment

Koncepcje

Obsługa wyjątków w Runtime współbieżności

Inne zasoby

Instruktaże Runtime współbieżności