std::promise<>
- 스레드 사이에서 "값 또는 예외를 공유" 할 수 있는 템플릿
- <future> 헤더
- promise 통해서 전달된 데이터는 std::future<>를 통해서 얻을 수 있다.
- set_value()는 한번만 사용할 수 있다.
- future()는 한번만 꺼낼 수 있다.
std::future<> 멤버 함수
- get() : 결과를 꺼내기. (한번만 사용 가능)
- wait() : 결과값이 준비될 때까지 대기
- wait_for() : 주어진 시간 만큼 대기
- wait_until() : 주어진 시간까지 대기
-> wait_for/wait_until 함수의 반환값
- std::future_status::ready : 결과값이 준비 됨.
- std::future_status::timeout : 시간초과
- std::future_status::defferred : 연산을 수행할 함수가 아직 시작 안됨. async()함수에서 사용.
- share() : shared_future 얻기
- valid() : 유효성 확인
1. std::promise & std::future 기본예제
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
using namespace std::literals;
void add(std::promise<int>&& p, int a, int b) {
int s = a + b;
std::this_thread::sleep_for(1s);
p.set_value(s);
/* NOTE: 스레드가 끝날때 set_value를 수행하는 함수도 있음
p.set_value_at_thread_exit(s); */
}
int main() {
std::promise<int> pm;
std::future<int> ft = pm.get_future();
std::thread t(add, std::move(pm), 10, 20);
int ret = ft.get(); // blocking : thread가 끝날때까지
std::cout << ret << std::endl;
t.join();
}
2. std::promise & std::future로 예외 전달하기
#include <iostream>
#include <thread>
#include <future>
void divide(std::promise<int>& p, int a, int b) {
try {
if (b == 0)
throw std::runtime_error("divide by zero");
p.set_value(a/b);
}
catch(...) {
p.set_exception(std::current_exception());
/* NOTE: 스레드가 종료했을때 보내는 함수도 있다.
p.set_exception_at_thread_exit(std::current_exception()); */
}
}
int main() {
std::promise<int> pm;
std::future<int> ft = pm.get_future();
std::thread t(divide, std::ref(pm), 10, 0);
try {
int ret = ft.get();
}
catch(std::exception &e) {
std::cout << e.what() << std::endl;
}
t.join();
}
3. std::promise로 void형 전달하기
#include <iostream>
#include <thread>
#include <future>
#include <vector>
#include <numeric>
int main() {
std::vector<int> v1 = {1,2,3,4,5,6,7,8,9,10};
std::vecor<int> v2(10);
std::promise<void> pm1;
std::future<void> ft1 = pm1.get_futre();
std::promise<int> pm2;
std::future<int> ft2 = pm2.get_future();
std::thread t([&]{
std::partial_sum(v1.begin(), v1.end(), v2.begin()); // 부분합 구하기
pm1.set_value(); // 1번째 연산이 종료되었음을 알린다.
int s = std::accumulate(v2.begin(), v2.end(), 0); // 구간의 합 구하기
pm2.set_value(s); // 2번째 연산이 종료되었음을 알린다.
});
ft1.get();
for (auto n : v2)
std:;cout << n << ",";
int ret = ft2.get();
std::cout << ret << std::endl;
t.join();
}
4. std::future의 wait 예제
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
using namespace std::literals;
void add(std::promise<int>&& p, int a, int b) {
std::this_thread::sleep_for(3s);
p.set_value(a+b);
}
int main() {
std::promise<int> pm;
std::future<int> ft = pm.get_futre();
std::thread t(add, std::move(pm), 10, 20);
std::future_status ret = ft.wait_for(2s);
if (ret == std::future_status::ready)
std::cout << "ready!" << std::endl;
else if (ret == std::future_status::timeout)
std::cout << "timeout!" << std::endl;
else
std::cout << "deffered!" << std::endl;
t.join();
}
5. std::shared_future 예제
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
using namespace std::literals;
void add(std::promise<int>&& p, int a, int b) {
std::this_thread::sleep_for(1s);
p.set_value(a + b);
}
void consume(std::sharead_future<int> sf) {
sf.get();
std::cout << "finish foo" << std::endl;
}
int main() {
std::promise<int> pm;
std::future<int> ft = pm.get_future();
// std::future<int> ft2 = ft; //error
std::shared_future<int> sft = ft.share();
std::thread t(add, std::move(pm), 10, 20);
std::thread t1(consume, sft);
std::thread t2(consume, sft);
t.join();
t1.join();
t2.join();
}
728x90
'Language > C++' 카테고리의 다른 글
[C++] std::async (0) | 2024.12.20 |
---|---|
[C++] std::packaged_task (0) | 2024.12.18 |
[C++] std::ref, std::reference_wrapper (1) | 2023.09.01 |
[C++] std::thread (0) | 2023.09.01 |
[C++] std::chrono (0) | 2023.09.01 |
댓글