포스트

[C++] std::async 사용해보기

async 소개

C++에서 스레드를 사용한 작업은 직접 스레드를 생성하고 종료시켰습니다.

하지만 std::async 에 어떤 함수를 전달한다면, 이전 스레드 관리 방법과 다르게

알아서 스레드를 만들어 Thread Pool 로 객체를 관리하고

해당 함수를 비동기적으로 실행한 뒤 결과값을 future 에 전달합니다.

async 사용법

1
2
3
4
5
6
7
8
9
10
void for_print(std::string in)
{
	for (int i = 0; i < 4; ++i)
	{
		printf("[%s] : %d\n", in.c_str(), i);
	}
}

std::future<void> A = std::async(std::launch::async, for_print, "Func A");
std::future<void> B = std::async(std::launch::deferred, for_print, "Func B");

async 는 실행할 함수를 필수 사항으로 입력받고

선택 사항으로 함수의 실행 방법과 매개 변수를 전달 받습니다.

std::future std::async(**실행 방법, 실행 함수, 매개 변수**)

실행 방법

  1. std::launch::async: 바로 쓰레드를 생성해서 인자로 전달된 함수를 실행합니다.
  2. std::launch::deferred: future 의 .get() 함수가 호출되었을 때 실행합니다. (새로운 쓰레드를 생성하지 않습니다.)

실행 함수

  1. async로 실행할 함수의 이름을 전달합니다.

매개 변수

  1. 실행 함수가 받을 매개 변수들을 전달합니다.

반환 객체 std::future

  1. (반환 객체).wait(): 결과를 받을 때 까지 대기합니다.
  2. (반환 객체).get(): 결과를 받습니다.

std::future().get() 은 객체를 **이동**시켜 반환하므로 .get() 을 중복실해하면 오류가 발생합니다.


오류 검출

1
2
3
4
5
6
7
8
9
10
11
12
13
auto D = std::async(std::launch::async, for_print, "Func D");
std::future<int> E;

try {
	printf("User Get Function Start!\n");
	D.get();
	E.get();
}
catch (const std::future_error& e)
{
	std::cout << "Caught a future error with code \"" << e.code()
		<< "\"\nMessage: \"" << e.what() << "\"\n";
}

async 객체를 실행하는 중 오류가 발생했을 때 future_error 객체를 반환합니다.

future_error 객체의 .code() 메소드와 .what() 메소드를 통해 오류 번호와 원인을 알 수 있습니다.


일정 시간마다 상태 확인하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bool check_prime(int in)
{
	for (int i = 2; i < in; ++i)
		if (in % i == 0)
			return false;
	return true;
}

// ...

int num = 444444443;
std::future<bool> F = std::async(check_prime, num);

std::chrono::milliseconds du_time(100);
while (F.wait_for(du_time) != std::future_status::ready)
{
	printf(".");
}

비동기로 실행되는 객체인 만큼 일정한 시간마다 객체의 상태를 확인할 수 있습니다.

.wait_for(std::chrono) 메소드를 사용하면 전달받은 std::chrono 시간마다 객체의 현재 상태를 반환합니다.

위 코드는 F 객체가 완료될 때 까지 “printf(“.”)”를 실행하는 코드입니다.


이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.