Thread_09_C++ Future
1. Future
간단한 작업을 처리할 때 사용하는 C++ 문법
1회성의 이벤트나 간소한 작업을 수행할 때 mutex, condition_variable 까지 쓰지 않고 Future 를 사용 비동기 방식으로 작업(이벤트)을 처리
예시코드
#include <iostream>
#include <windows.h>
#include <future> //future 헤더파일 필요
//간단한 작업함수
int Calculate()
{
int sum = 0;
for (int i = 0; i < 100000; ++i)
sum += 1;
return sum;
}
int main()
{
//future 선언
std::future<int> future = std::async(std::launch::deferred, Calculate);
/*
다른 작업 수행
*/
std::future_status status = future.wait_for(std::chrono::seconds(1)); //1초 동안 대기
if (status == std::future_status::ready)
{
//ready 일 경우 일감이 완료된 상태
//아래의 그냥 get을 쓰나 if 에서 ready일 때 가져오나 결과는 같음
}
int sum = future.get(); //이 때 결과값을 가져온다.
std::cout << sum << std::endl;
return 0;
}
중간에 std::launch::async
가 있는데 future에는 몇 가지 모드가 존재한다
- async
std::future<int> future = std::async(std::launch::async, Calculate);
별도의 Thread를 만들어서 작업을 수행 생성된 시점부터 작업을 수행하며 작업이 만약 다 끝나지 않았다면
future.get()
을 수행할 때 완료될 때까지 대기 - deferred
std::future<int> future = std::async(std::launch::deferred, Calculate);
Thread를 만들지 않고 우선 선언을 해서 작업을 등록하고 실행은 하지 않는다
즉, 바로 작업을 시작하지 않기 때문에 ==지연된 처리(Lazy Evaluation)==라고도 함
작업 시작은future.get()
이 호출되었을 때 시작하고 완료될때까지 기다리고 값을 가져옴
2. Promise
다른 곳에서 작업된 값을 Promise와 Future를 이용해 가져옴
future에 promise를 등록한 뒤 다른 Thread에 Promise를 [[Move Semantics|rvalue]] 를 이용해 넘겨주면 promise를 이용해서 값을 전달받을 수 있다
#include <iostream>
#include <windows.h>
#include <thread>
#include <future>
using namespace std;
//rvalue 로 promise를 받음
void PromiseWorker(std::promise<string>&& promise)
{
promise.set_value("promise message");
}
int main()
{
std::promise<string> promise;
std::future<string> future = promise.get_future(); //future와 promise 연동작업
//다른 Thread에 작업을 시키고 해당 값을 가져올 수 있다
std::thread t(PromiseWorker, std::move(promise)); //promise 전달
//연동되었으므로 get을 하면 message를 받을 수 있다
string message = future.get();
cout << message << endl;
t.join();
return 0;
}
3. Packaged_task
Promise가 변수를 받는 것이라면 packaged_task
는 함수를 전달함
#include <iostream>
#include <windows.h>
#include <thread>
#include <future>
using namespace std;
//packaged_task가 가지고 있는 반환값이 있는 함수
int Calculate()
{
int sum = 0;
for (int i = 0; i < 100; i++)
sum += i;
return sum;
}
//packaged_task를 전달해줄 Thread
void TaskWorker(std::packaged_task<int(void)>&& task)
{
task();
}
int main()
{
std::packaged_task<int(void)> task(Calculate); //함수를 등록
std::future<int> future = task.get_future(); //반환
std::thread t(TaskWorker, std::move(task)); //Thread 생성, packaged_task 전달
int sum = future.get(); //get으로 calcuate의 반환값을 가져올 수 있다
cout << sum << endl;
t.join();
return 0;
}
그다지 많이 사용되지는 않지만 이런게 있다 정도로 하고 넘어가자
댓글남기기