하나의 작은 함수를 비동기 방식을 활용할 때 사용한다.
스레드를 따로 만들지 않아도, 자동으로 멀티스레드 환경을 제공한다.
스레드 관리가 필요 없으므로 로딩 등 가벼운 방식에서 사용하면 효율적이다.
mutex, condition_variable까지 가지 않고 일회성으로 처리할 수 있는 단순한 것들을 처리할 때 용이하다.
비동기와 멀티스레드는 같은 개념이 아니다.
비동기 호출이 된다면 멀티스레드로 호출이 될 수 있다. (luanch::async)
Future
원하는 함수를 비동기적으로 실행한다.
#include <future>
/*
1. launch::deferred -> lazy evaluation 지연해서 실행-> 순서만 뒤로 미룬다
2. launch::async -> 별도의 스레드를 만들어서 병렬로 실행 -> 멀티스레드 활용
3. launch::deferred | async -> 둘 중 알아서 골라서 진행
*/
// 커맨드 패턴
future<int64> future = async(launch::async, 함수명);
future_status status = future.wait_for(1ms); // 생략 가능
if (status == future_status::ready) {
int64 sum = future.get();
}
future 비동기 멀티스레드 방식 사용방법
#include "pch.h"
#include "CorePch.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <future>
int64 Calculate() {
int64 sum = 0;
for (int32 i = 0; i < 1'000'000; i++) {
sum += i;
}
return sum;
}
int main()
{
// 비동기 수행
future<int64> future = async(launch::async, Calculate);
future_status status = future.wait_for(1ms); // 생략 가능
if (status == future_status::ready) {
int64 sum = future.get();
}
}
멤버함수 호출시 사용방법
class Knight {
public:
int64 GetHP() { return 100; }
};
Knight knight;
std::future<int64> future2 = async(launch::async, &Knight::GetHP, knight); // knight.GetHP()
Promise
결과물을 promise를 통해 future로 받아온다.
std::promise와 std::future
#include "pch.h"
#include "CorePch.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <future>
void PromiseWorker(std::promise<string>&& promise) {
promise.set_value("Secret Message");
}
int main()
{
// std::promise
// 미래(std::promise)에 결과물을 반환해줄거라 약속(std::promise)
std::promise<string> promise;
std:future<string> future = promise.get_future();
// t 스레드에게 PromiseWorker 함수 소유권을 넘겨준다.
thread t(PromiseWorker, std::move(promise));
string message = future.get(); //future.get() 함수가 호출되면 future 객체는 empty상태로 돌아간다.
cout << message << endl;
t.join();
}
Packaged_task
원하는 함수의 실행 결과를 packaged_task를 통해 future로 받아온다.
std::packaged_task
#include "pch.h"
#include "CorePch.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <future>
int64 Calculate() {
int64 sum = 0;
for (int32 i = 0; i < 1'000'000; i++) {
sum += i;
}
return sum;
}
void TaskWorker(std::packaged_task<int64(void)>&& task) {
task();
}
int main()
{
// packaged_task<함수 리턴타입(함수 매개변수 타입)>
std::packaged_task<int64(void)> task(Calculate);
std::future<int64> future = task.get_future();
/*
매개변수로 들어간 Calculate 함수의 결과값을 future객체가 받아올 수 있다.
*/
thread t(TaskWorker, std::move(task));
int sum = future.get();
cout << sum << endl;
}
'Server > C++' 카테고리의 다른 글
CPU 파이프라인 - 명령어 파이프라인 (0) | 2024.07.30 |
---|---|
캐시(Cache)와 CPU (1) | 2024.07.30 |
조건변수 (Condition Variable) (0) | 2024.07.30 |
커널 오브젝트 Event를 사용한 프로그램 동작 (0) | 2024.07.30 |
슬립(Sleep)과 운영체제 (0) | 2024.07.30 |