Program Language/C & C++

[C++] std::async

야곰야곰+책벌레 2021. 10. 19. 13:23
728x90
반응형

  std::async는 std::task 클래스 기반으로 만들어진 클래스로 thread를 만들 때 사용한다. std::async는 std::thread와 달리 내부적으로 thread pool을 만들어 thread를 관리하며 std::thread보다 안정적이며 프로그래머가 사용하기 편하다. std::async는 반환 값을 std::future로 받는다.

#include <iostream>
#include <future>
using namespace std;

void print(char id)
{
	for (int i = 0; i < 10; i++)
	{
		printf("thread no : %c , Count : %d \n", id, i);
	}
}

int main()
{
	std::future<void> a = std::async(std::launch::async, print, 'a');
	std::future<void> b = std::async(std::launch::deferred, print, 'b');
	std::future<void> c = std::async(print, 'c');
	
	b.get();
	return 0;
}

std::async에서 첫 번째 인자는 특성을 나타낸다.

std::launch::async : std::async 호출과 동시에 바로 thread를 생성하여 인자로 전달된 함수를 실행한다.
std::launch::deferred : std::async 함수가 반환한 std::future 객체의 get or wait 함수가 호출되면 실행된다.

그리고 std::launch는 생략될 수 있다.

std::future_error

  정의되지 않는 future에 대해서 get() 호출 시 예외 처리해주려면 다음과 같이 할 수 있다.

#include <iostream>
#include <future>
using namespace std;

void print(char id)
{
	for (int i = 0; i < 10; i++)
	{
		printf("thread no : %c , Count : %d \n", id, i);
	}
}

int main()
{
	std::future<void> a = std::async(std::launch::async, print, 'a');
	std::future<void> future_a;
	
	try
	{
		a.get();
		future_a.get(); // error가 일어나는 부분
	}
	catch (const std::future_error& e)
	{
		std::cout << "future_error : " << e.code() << " , message : " << e.what() << "\n";
	}
	return 0;
}

std::future.wait_for()

  wait_for()는 해당 thread가 끝날 때까지의 상태를 반환해 준다. 인자 값으로는 std::chrono:: 클래스의 객체를 받는다. 시간을 지정해주고 해당 시간이 지남에 따라 thread 상태가 어떤지 알려준다.

#include <iostream>
#include <future>
#include <chrono>
using namespace std;

bool print(long count)
{
	long sum = 0;
	for (int i = 0; i < count; i++)
	{
		sum = i;
	}
	printf("\nsum : %d", sum);

	return true;
}

int main()
{
	std::future<bool> fut = std::async(std::launch::async, print, 9999999);
	
	cout << "checking, please wait";
	chrono::microseconds span(100);

	while (fut.wait_for(span) != std::future_status::ready)
	{
		cout << '.';
		cout.flush();
	}

	bool ret = fut.get();
	cout << "\n" << ret << endl;
	
	return 0;
}

thread가 진행하는 동안 지정한 100us 마다 '.'을 하나씩 출력한다.

728x90
반응형