반응형
en.cppreference.com/w/cpp/thread/async
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 |
댓글