C++11 ~
C++ 에서 비동기 작업을 하기 위해 만들어진 library.
future을 include 하여 사용 가능하다.
C++에서 비동기 작업을 수행하는 또다른 library인 thread와의 차이는
https://donot-simsim.tistory.com/35
https://donot-simsim.tistory.com/37
요렇다.
async 사용 시엔 두 개의 launch policy를 줄 수 있다.
launch::async는
- 만들자마자 비동기적으로 실행된다.
- 소멸되기 전, 해당되는 작업이 다 끝날 때까지 기다린다.
launch::deferred는
- 만들어도 실제로 해당 future object로부터 get 하기 전까진 아무일도 하지 않는다.
- 만든 후에 해당 future로 아무것도 하지 않으면 바로 소멸된다.
먼저 launch::async.
#include <iostream>
#include <future>
using namespace std;
void asyncFunc(const string& msg) {
cout << msg << endl;
this_thread::sleep_for(chrono::seconds(5));
cout << "async out" << endl;
}
int main()
{
{
auto a1 = async(launch::async, asyncFunc, "launch with async");
}
{
auto a2 = async(launch::async, asyncFunc, "launch with async");
}
{
auto a3 = async(launch::async, asyncFunc, "launch with async");
}
return 0;
}
위의 코드를 실행하면
위처럼 결과가 나온다.
a1, a2, a3를 각각의 {} 로 감싼 상태이다.
괄호를 나갈 때 내부에 있는 변수들을 전부 소멸시키고 나간다.
만약 a1을 무시하고 그냥 나갔다면 출력이 순차적으로 나오지 않을 텐데, 소멸 될 때 각각의 asyncFunc들이 전부 끝날 때 까지 기다리느라 위처럼 출력이 나오게 되었다.
반면 launch::deferred는
#include <iostream>
#include <future>
using namespace std;
void asyncFunc(const string& msg) {
cout << msg << endl;
this_thread::sleep_for(chrono::seconds(5));
cout << "deferred out" << endl;
}
int main()
{
{
auto a1 = async(launch::deferred, asyncFunc, "a1 launch with deferred");
}
{
auto a2 = async(launch::deferred, asyncFunc, "a2 launch with deferred");
}
{
auto a3 = async(launch::deferred, asyncFunc, "a3 launch with deferred");
}
return 0;
}
아무것도 나오지 않는다.
deferred를 policy로 주면 해당 값을 얻어올 때 까지 함수의 실행을 미루게 된다. 그러다 보니 future object를 넘겨도 asyncFunc이 바로 실행되지 않고, 소멸 될 때 실행되고 있는 함수가 아무것도 없으니 빠르게 사라진다.
{
auto a2 = async(launch::deferred, asyncFunc, "a2 launch with deferred");
a2.get();
}
다만 코드를 살짝 바꿔서, 중간에 a2.get()을 넣으면
이런 식으로, get을 한 부분만 asyncFunc을 돌게 된다.
만들자마자 바로 돌게끔. thread처럼 쓰고 싶다
-> launch::async
만들어 두고, 필요할 떄 사용하고 싶다
-> launch::deferred.
참고로, async를 생성할 때 아무런 옵션도 주지 않으면
std::launch::async | std::launch::deferred 라는 policy를 준 것처럼 동작한다고 한다.
async, deferred 두 개의 정책을 동시에 주면 어떻게 되나 궁금해서 찾아봤는데
이러한 공식 문서와
Chapter 30.6.8 of ISO IEC 14882-2011
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf
[ Note: If this policy is specified together with other policies, such as when using a policy value of launch::async | launch::deferred, implementations should defer invocation or the selection of the policy when no more concurrency can be effectively exploited. — end note ]
이런 글이 있더라.
결국 보면, 사용할 수 있는 cpu core가 있다면 async 로 돌리고, 그렇지 않다면 deferred로 알아서 정책을 선택한다고 하는 듯 하다.
그러니.. 엥간하면 정책을 정해서 async를 사용하도록 하자.
*잘못된 정보는 알려주시면 감사히 수정하겠습니다.
'C++ > STL' 카테고리의 다른 글
[C++17] Optional (0) | 2023.05.28 |
---|---|
[C++20] Concepts (1) | 2023.05.23 |
[C++] std::async, std::thread (2) (0) | 2023.04.10 |
[C++] std::async, std::thread (1) (0) | 2023.04.09 |
[C++17] std::filesystem::path (0) | 2023.04.04 |