본문 바로가기
💻 programming/c++

[c++] async

by 연구원-A 2020. 12. 15.
반응형

en.cppreference.com/w/cpp/thread/async

 

std::async - cppreference.com

(1) (since C++11) (until C++17) template< class Function, class... Args> std::future ,                                  std::decay_t ...>>     async( Function&& f, Args&&... args ); (since C++17) (until C++20) template< class Function, c

en.cppreference.com

async는 일종의 함수 템플릿 (function template)입니다. async를 사용하면 함수 f를 비동기적으로 실행하고 함수 f의 반환 값을 std::future로 반환합니다.

2020.12.15 - [c++ language/basics] - [c++] functor (function object)

2020.12.15 - [c++ language/library] - [c++] future

 

async의 특징

async는 promise나 packaged_task와 달리 별도로 thread를 생성할 필요 없이 함수만 전달하면 아예 thread를 알아서 만들어서 함수를 비동기적으로 실행하고 std::future를 전달합니다.

 

aync vs. deferred

aync 함수는 인자를 가질 수 있습니다. async에 전달할 수 있는 인자는 std::launch::aysync와 std::launch::deferred 가 있습니다.

  • std::launch::async: async 함수 템플릿을 호출하면 바로 thread를 생성해서 인자로 전달된 함수를 실행한다 (enable asynchronous evaluation)
  • std::launch::deferred: async 함수가 반환한 std::future 객체의 get 함수가 호출되면 함수를 실행다 (enable lazy evaluation; thread가 새로 생성되지는 않음)

 

예제 코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <future>
#include <string>
#include <mutex>
 
std::mutex m;
struct X {
    void foo(int i, const std::string& str) {
        std::lock_guard<std::mutex> lk(m);
        std::cout << str << ' ' << i << '\n';
    }
    void bar(const std::string& str) {
        std::lock_guard<std::mutex> lk(m);
        std::cout << str << '\n';
    }
    int operator()(int i) {
        std::lock_guard<std::mutex> lk(m);
        std::cout << i << '\n';
        return i + 10;
    }
};
 
template <typename RandomIt>
int parallel_sum(RandomIt beg, RandomIt end)
{
    auto len = end - beg;
    if (len < 1000)
        return std::accumulate(beg, end, 0);
 
    RandomIt mid = beg + len/2;
    auto handle = std::async(std::launch::async,
                             parallel_sum<RandomIt>, mid, end);
    int sum = parallel_sum(beg, mid);
    return sum + handle.get();
}
 
int main()
{
    std::vector<int> v(10000, 1);
    std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';
 
    X x;
    // Calls (&x)->foo(42, "Hello") with default policy:
    // may print "Hello 42" concurrently or defer execution
    auto a1 = std::async(&X::foo, &x, 42, "Hello");
    // Calls x.bar("world!") with deferred policy
    // prints "world!" when a2.get() or a2.wait() is called
    auto a2 = std::async(std::launch::deferred, &X::bar, x, "world!");
    // Calls X()(43); with async policy
    // prints "43" concurrently
    auto a3 = std::async(std::launch::async, X(), 43);
    a2.wait();                     // prints "world!"
    std::cout << a3.get() << '\n'; // prints "53"
} // if a1 is not done at this point, destructor of a1 prints "Hello 42" here
반응형

'💻 programming > c++' 카테고리의 다른 글

[c++] optional  (0) 2020.12.15
[c++] move  (0) 2020.12.15
[c++] perfect forwarding (완벽한 전달)  (0) 2020.12.15
[c++] packaged task  (0) 2020.12.15
[c++] future  (0) 2020.12.15

댓글