Aracılığıyla paylaş


İzlenecek yol: Vadeli İşlemleri Uygulama

Bu konu başlığında, uygulamanızda vadeli işlemlerin nasıl uygulanacakları gösterilmektedir. Konu başlığında Eşzamanlılık Çalışma Zamanı'ndaki mevcut işlevlerin daha fazlasını yapabilen bir şekilde nasıl birleştirildiği gösterilmektedir.

Önemli

Bu konu başlığında gösterim amacıyla vadeli işlem kavramı gösterilmektedir. Daha sonra kullanmak üzere bir değer hesaplayan zaman uyumsuz bir göreve ihtiyacınız olduğunda std::future veya concurrency::task kullanmanızı öneririz.

Görev, ek, daha ayrıntılı hesaplamalar halinde ayrıştırılabilir bir hesaplamadır. Gelecek, bir değeri daha sonra kullanmak üzere hesaplayan zaman uyumsuz bir görevdir.

Vadeli işlemleri uygulamak için bu konu sınıfını async_future tanımlar. sınıfı async_future Eşzamanlılık Çalışma Zamanı'nın şu bileşenlerini kullanır: eşzamanlılık::task_group sınıfı ve eşzamanlılık::single_assignment sınıfı. async_future sınıfı, bir değeri zaman uyumsuz olarak hesaplamak için sınıfını ve single_assignment hesaplama sonucunu depolamak için sınıfını kullanırtask_group. sınıfının oluşturucusunun async_future sonucu hesaplayan bir iş işlevi alır ve get yöntemi sonucu alır.

Async_future sınıfı uygulamak için

  1. Sonuçta elde edilen hesaplamanın türüne göre parametreleştirilmiş adlı async_future bir şablon sınıfı bildirin. private Ve bölümlerini bu sınıfa ekleyinpublic.
template <typename T>
class async_future
{
public:
private:
};
  1. private sınıfının bölümünde async_future ve task_group single_assignment veri üyesini bildirin.
// Executes the asynchronous work function.
task_group _tasks;

// Stores the result of the asynchronous work function.
single_assignment<T> _value;
  1. public sınıfının bölümünde async_future oluşturucuyu uygulayın. Oluşturucu, sonucu hesaplayan iş işlevinde parametreleştirilmiş bir şablondur. Oluşturucu, iş işlevini veri üyesinde task_group zaman uyumsuz olarak yürütür ve sonucu single_assignment veri üyesine yazmak için concurrency::send işlevini kullanır.
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());
    });
}
  1. public sınıfının bölümünde async_future yıkıcıyı uygulayın. Yıkıcı görevin tamamlanmasını bekler.
~async_future()
{
   // Wait for the task to finish.
   _tasks.wait();
}
  1. public sınıfının bölümünde async_future yöntemini uygulayınget. Bu yöntem, iş işlevinin sonucunu almak için concurrency::receive işlevini kullanır.
// 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); 
}

Örnek

Açıklama

Aşağıdaki örnekte sınıfın tamamı async_future ve kullanımına ilişkin bir örnek gösterilmektedir. İşlev, wmain 10.000 rastgele tamsayı değeri içeren bir std::vector nesnesi oluşturur. Daha sonra nesnede vector bulunan en küçük ve en büyük değerleri bulmak için nesneleri kullanırasync_future.

Kod

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

Açıklamalar

Bu örnek aşağıdaki çıkışı oluşturur:

smallest: 0
largest:  9999
average:  4981

Örnek, hesaplamanın sonuçlarını almak için yöntemini kullanır async_future::get . async_future::get yöntemi, hesaplama hala etkinse hesaplamanın bitmesini bekler.

Güçlü Programlama

sınıfını async_future iş işlevi tarafından oluşturulan özel durumları işleyecek şekilde genişletmek için yöntemini eşzamanlılık::task_group::wait yöntemini çağıracak şekilde değiştirinasync_future::get. yöntemi, task_group::wait iş işlevi tarafından oluşturulan tüm özel durumları oluşturur.

Aşağıdaki örnekte sınıfın değiştirilmiş sürümü gösterilmektedir async_future . İşlev, wmain nesnenin async_future sonucunu yazdırmak veya iş işlevi tarafından oluşturulan özel durumun değerini yazdırmak için bir try-catch blok kullanır.

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

Bu örnek aşağıdaki çıkışı oluşturur:

caught exception: error

Eşzamanlılık Çalışma Zamanı'nda özel durum işleme modeli hakkında daha fazla bilgi için bkz . Özel Durum İşleme.

Kod Derleniyor

Örnek kodu kopyalayıp bir Visual Studio projesine yapıştırın veya adlı futures.cpp bir dosyaya yapıştırın ve ardından bir Visual Studio Komut İstemi penceresinde aşağıdaki komutu çalıştırın.

cl.exe /EHsc futures.cpp

Ayrıca bkz.

Eşzamanlılık Çalışma Zamanı İzlenecek Yollar
Özel Durum İşleme
task_group Sınıfı
single_assignment Sınıfı