다음을 통해 공유


연습: 미래 구현

이 항목에서는 응용 프로그램에서 미래를 구현하는 방법을 보여 줍니다.여기에서는 동시성 런타임의 기존 기능을 결합하여 더 많은 작업을 수행하는 방법을 보여 줍니다.

중요중요

이 항목에서는 데모용 퓨처의 개념을 보여 줍니다.사용 하는 것이 좋습니다 std::future 또는 concurrency::task 에서 나중에 사용할 값을 계산 하는 비동기 작업을 필요로 합니다.

작업은 좀 더 세분화된 추가 계산으로 분해할 수 있는 계산입니다.미래는 나중에 사용할 수 있도록 값을 계산하는 비동기적 작업입니다.

미래를 구현하기 위해 이 항목에서는 async_future 클래스를 정의합니다.async_future 클래스 사용 하 여 이러한 구성 요소의 동시성 런타임:는 concurrency::task_group 클래스 및 concurrency::single_assignment 클래스입니다.async_future 클래스는 task_group 클래스를 사용하여 값을 비동기적으로 계산하고 single_assignment 클래스를 사용하여 계산 결과를 저장합니다.async_future 클래스의 생성자는 결과를 계산하는 작업 함수를 사용하고 get 메서드는 결과를 검색합니다.

Async_future 클래스를 구현.

  1. 결과 계산의 형식에 대해 매개 변수가 있는 async_future 템플릿 클래스를 선언합니다.public 및 private 섹션을 이 클래스에 추가합니다.

    template <typename T>
    class async_future
    {
    public:
    private:
    };
    
  2. async_future 클래스의 private 섹션에서 task_groupsingle_assignment 데이터 멤버를 선언합니다.

    // Executes the asynchronous work function.
    task_group _tasks;
    
    // Stores the result of the asynchronous work function.
    single_assignment<T> _value;
    
  3. async_future 클래스의 public 섹션에서 생성자를 구현합니다.생성자는 결과를 계산하는 작업 함수에 대한 매개 변수가 있는 템플릿입니다.생성자 함수에서 작업을 비동기적으로 실행의 task_group 데이터 멤버 및 용도 concurrency::send 함수는 결과를 작성할 수는 single_assignment 데이터 멤버.

    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. async_future 클래스의 public 섹션에서 소멸자를 구현합니다.소멸자는 작업이 끝날 때까지 기다립니다.

    ~async_future()
    {
       // Wait for the task to finish.
       _tasks.wait();
    }
    
  5. async_future 클래스의 public 섹션에서 get 메서드를 구현합니다.이 메서드를 사용 하는 concurrency::receive 작업 함수의 결과 검색 하는 함수입니다.

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

예제

Dd764564.collapse_all(ko-kr,VS.110).gif설명

다음 예제에서는 전체 async_future 클래스 및 이 클래스의 사용법을 보여 줍니다.wmain 함수는 임의의 정수 값이 10,000개 포함된 std::vector 개체를 만듭니다.그런 다음 async_future 개체를 사용하여 vector 개체에 포함된 값 중에서 가장 작은 값과 가장 큰 값을 찾습니다.

Dd764564.collapse_all(ko-kr,VS.110).gif코드

// 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(ko-kr,VS.110).gif설명

이 예제의 결과는 다음과 같습니다.

smallest: 0
largest:  9999
average:  4981

이 예제에서는 async_future::get 메서드를 사용하여 계산 결과를 검색합니다.async_future::get 메서드는 계산이 아직 활성 상태인 경우 끝날 때까지 기다립니다.

강력한 프로그래밍

확장 하는 async_future 수정, 작업 함수에서 throw 된 예외를 처리 하는 클래스는 async_future::get 메서드를 호출 하는 concurrency::task_group::wait 메서드.task_group::wait 메서드는 작업 함수에 의해 생성된 예외를 throw합니다.

다음 예제에서는 async_future 클래스의 수정된 버전을 보여 줍니다.wmain 함수는 try-catch 블록을 사용하여 async_future 개체의 결과를 인쇄하거나, 작업 함수에서 생성되는 예외의 값을 인쇄합니다.

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

이 예제의 결과는 다음과 같습니다.

caught exception: error

동시성 런타임의 예외 처리 모델에 대한 자세한 내용은 동시성 런타임에서 예외 처리를 참조하십시오.

코드 컴파일

예제 코드를 복사 하 고 Visual Studio 프로젝트에 붙여 또는 라는 파일에 붙여 futures.cpp 및 다음 Visual Studio 명령 프롬프트 창에서 다음 명령을 실행 합니다.

cl.exe /EHsc futures.cpp

참고 항목

참조

task_group 클래스

single_assignment 클래스

개념

동시성 런타임에서 예외 처리

기타 리소스

동시성 런타임 연습