İ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
- 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:
};
private
sınıfının bölümündeasync_future
vetask_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;
public
sınıfının bölümündeasync_future
oluşturucuyu uygulayın. Oluşturucu, sonucu hesaplayan iş işlevinde parametreleştirilmiş bir şablondur. Oluşturucu, iş işlevini veri üyesindetask_group
zaman uyumsuz olarak yürütür ve sonucusingle_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());
});
}
public
sınıfının bölümündeasync_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();
}
public
sınıfının bölümündeasync_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ı