반응형
thread와 task는 사용 목적과 추상화 정도가 다르다
thread는 원시적인 병렬처리 방법이고, thread를 사용해 task는 데이터를 동기화하는 방법이다
⭐ 다시 말하면 데이터를 동기화 할 때는 굳이 개발자가 직접 thread를 생성하고, mutex를 이용하기 보다는
⭐ c++에서 제공하는 task를 이용하는 것이 좋다
⭐ 심지어 task를 이용할 때 thread를 생성할 수도 있고, 필요하면 생성하지 않고 동기화 할 수도 있다.
- thread는 말그대로 병렬처리를 위한 흐름을 생성하고 제어하기 위한 기본적인 함수를 제공한다 (join, detach 등)
- async와 같은 task는 promise-future 사이에 통신 흐름을 만든다
- future에서 get 함수를 호출하여 promise와 동기화를 수행한다
- 동기화 과정에서 thread 생성 여부는 aynsc에 전달하는 인자에 따라 다르게 동작한다
- std::launch::async: async 함수 템플릿을 호출하면 바로 thread를 생성해서 인자로 전달된 함수를 실행한다 (enable asynchronous evaluation)
- std::launch::deferred: async 함수가 반환한 std::future 객체의 get 함수가 호출되면 함수를 실행다 (enable lazy evaluation; thread가 새로 생성되지는 않음)
이외에도 포함해야하는 헤더, 쓰레드 생성 여부 등이 각각 다르다.
cf. async를 이용한 동기화 예제 코드
#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
참고 링크: https://www.modernescpp.com/index.php/tasks
반응형
'💻 programming > c++' 카테고리의 다른 글
[c++] logger 클래스 만들기 (0) | 2021.08.04 |
---|---|
[c++] timer 클래스 만들기 (0) | 2021.08.04 |
[c++] thread (0) | 2021.08.04 |
[c++] lvalue reference and rvalue reference (0) | 2021.08.04 |
[c++] condition variable (조건 변수) (0) | 2020.12.17 |
댓글