SW 그리고 아빠 엔지니어링 중...

아는 만큼 보이고, 경험해봐야 알 수 있고, 자꾸 써야 내 것이 된다.

L C++/Concurrency

[Utilities] thread를 잘 사용하기 위한 std::reference_wrapper (std::ref) (활용 예시 추가)

보리남편 김 주부 2023. 5. 28. 12:08

문제점


thread 내에서 동작한 값을 얻을 수 있는 리턴 값이나 인자 값을 받을 수 없을 때 인자수를 조정할 수 있는 bind를 이용할 수 있지만 binding 하는 함수의 인자를 참조해도 참조가 되지 않는다.

 

해결 방법


함수자체를 포인터를 넘겨서 값을 받아오거나(call by address),  std::reference_wrapper(혹은 std::ref)를 사용하면 참조가 안 되는 문제를 해결할 수 있다.

 

활용 예시


다음은 std::bind를 이용하여 인자수를 조정하고 foo 함수의 결과를 얻는 예제코드이다.

  • main 함수에 n = 0 의 값을 foo 함수 내에서 처리된 100의 값을 얻고 싶다.

 

  • 코드 실행해보기 (아래 우측 상단 아이콘 선택 시 실행 가능)

 

 

 

  • 전체코드 한눈에 보기
더보기
#include <iostream>
#include <functional>

void foo(int& r)
{
	r = 100;
}

int main()
{
	std::function<void(void)> f;

	int n = 3;

	// thread에서 동작한 값을 얻을 수 있는 인자가 없을 때 인자수를 조정할 수 있는 bind를 이용할 수 있다.
	f = std::bind(&foo, n);
	f();
	std::cout << "f() n : " << n << std::endl;
	// => f는 내부적으로 "n"의 값 "0" 을 보관한다.

	// 0이 아닌 n 자체를 보관하게 하려면 아래 처럼 해야 합니다.
	f = std::bind(&foo, std::ref(n) );
	f();

	std::cout << "f() ref n : " << n << std::endl;
}
//결과
f() n : 3
f() ref n : 100

결과 :  bind 시 넘겨진 n의 값은 foo에서 참조 r로 받았지만 기대와 다르게 결과 값이 3이지만
std::ref (reference_wrapper 실행하는 함수)로 n을 전달하면 foo 내부에 값인 100을 얻어온다.

 

 

foo 함수는 참조를 이용해 입력받은 인자를 통해 호출주체에게 값을 넘기고 싶어 하지만
아래 예제에도 있었지만 함수 하나만 더 거쳐가도 이 참조 값은 보장이 되지 못하기에 참조를 이동시킬 수 있는 reference_wrapper (std::ref) 가 필요하다.

2023.05.28 - [언어/C++] - thread를 잘 사용하기 위해 필요한 템플릿 클래스 std::reference_wrapper (std::ref)

 

참고


* 본 글에 예제 코드는 코드누리 교육을 받으면서 제공된 샘플코드를 활용하였습니다.

728x90