| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
Tags
- Strongly Connected Component
- DP
- localstorage
- 강한 연결 요소
- 그래프 탐색
- Express.js
- Binary Lifting
- 분리 집합
- Github
- 게임 서버 아키텍처
- 이분 탐색
- Spin Lock
- Lock-free Stack
- trie
- PROJECT
- map
- 비트필드를 이용한 dp
- 자바스크립트
- 트라이
- ccw 알고리즘
- JavaScript
- R 그래프
- Prisma
- Behavior Design Pattern
- 2-SAT
- 최소 공통 조상
- LCA
- 비트마스킹
- SCC
- 벨만-포드
Archives
- Today
- Total
dh_0e
[C++/Game Server] future, promise, packaged_task 본문
std::future
- 무겁게 스레드를 직접 다루지 않고 미래의 값을 약속받는 방식
- JavaScript(node.js)의 async/await(비동기) 방식과 유사
- <future> 헤더 필요
std::future<int64> future = std::async(std::launch::async, Calculate);
- launch 정책과 실행할 함수를 입력값으로 사용
std::launch 정책
1) std::launch::deferred
- lazy evaluation(지연 실행)
- 요청 시점까지 대기(lazy evaluation), 스레드 생성 X
- main() -> 요청 -> 실행(호출)
2) std::launch::async
- 즉시 별도 스레드로 실행
- main() -> 별도의 스레드로 병렬 작업 실행
사용 예시
int Calculate() {
int sum = 0;
for (int i = 0; i < 100'000; i++) {
sum += i;
}
return sum;
}
int main()
{
{
std::future<int> future = std::async(std::launch::async, Calculate);
int sum = future.get();
}
return 0;
}
future.get();
- future 결과물을 반환
- 한 번 실행하면 future가 empty가 됨 (이후 호출시 오류)
future.wait_for(1ms);
- std::future_status 형식 반환
- 작업이 끝났는지 1초 동안 기다렸다 확인
- future.wait(): 바로 확인
class Knight
{
public:
int GetHp() { return 100; }
};
Knight knight;
std::future<int> future2 = std::async(std::launch::async, &Knight::GetHp, knight);
- 이런 식으로 객체(class)의 멤버 함수도 실행할 수 있음
- 객체에 의존적으로 호출이 되기 때문에 객체가 포함되어야 함
std::promise
- future에 값을 전달할 수 있도록 약속하는 객체
- 스레드 간 통신에서 유용하게 사용
사용 예시
void PromiseWorker(std::promise<string>&& promise)
{
promise.set_value("Secret Message");
}
int main()
{
{
std::promise<string> promise;
std::future<string> future = promise.get_future();
thread t(PromiseWorker, std::move(promise));
string message = future.get();
cout << message << endl;
t.join();
}
return 0;
}
- promise.set_value()를 호출하면 future.get()에서 결과를 받을 수 있음
- 전역 변수 없이 스레드 간 값 전달이 가능함
std::packaged_task
- promise는 값이었다면 packaged_task는 함수(작업 단위)를 future로 감싸는 객체
- promise와 구조는 비슷하지만 값을 직접 전달하는 게 아니라, 함수 실행 결과를 전달함
int Calculate() {
int sum = 0;
for (int i = 0; i < 100'000; i++) {
sum += i;
}
return sum;
}
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));
int sum = future.get();
cout << sum << endl;
}
return 0;
}
std::async vs std::promise vs std::packaged_task
| 항목 | std::async | std::promise | std::packaged_task |
| 주 역할 | 함수 실행 후 결과 받기 | 직접 값을 넘기기 | 함수 자체를 포장해 넘기기 |
| Future 생성 방식 | 내부에서 생성됨 | get_future()로 획득 | get_future()로 획득 |
| 실행 방식 | 자동 비동기/지연 실행 | 사용자가 직접 실행 | 사용자가 직접 실행 |
| thread 필요 여부 | 옵션에 따라 다름 | 직접 thread 생성해야 함 | 직접 thread 생성해야 함 |
정리
- std::future: 미래의 결과값을 보장받는 객체
- std::async: 함수 실행과 future를 연결
- std::promise: 값을 외부에서 전달해주는 약속
- std::packaged_task: 함수 전체를 포장해서 future로 전달
- 모두 mutex, condition_variable를 사용하기엔 단순한 작업을 처리할 수 있는, 특히 한 번 발생하는 이벤트에 유용한 객체들이다.
'C++ > Game Server' 카테고리의 다른 글
| [C++/Game Server] Thread Local Storage (0) | 2026.02.05 |
|---|---|
| [C++/Game Server] 동기화 방식과 메모리 정책 (memory_order) (1) | 2026.02.04 |
| [C++/Game Server] Spin Lock, Event Lock, Condition Variable (6) | 2025.08.05 |
| [C++/Game Server] Spin Lock, Volatile 변수 (1) | 2025.07.26 |
| [C++/Game Server] mutex, atomic, lock_guard, unique_lock (2) | 2025.07.24 |
