본문 바로가기
개발/C, C++

C++ - call_once로 함수를 한 번만 호출하기

by 피로물든딸기 2024. 1. 24.
반응형

C, C++ 전체 링크

 

test 함수는 처음 호출 되는 경우에만 init을 수행한다.

#include <iostream>

using namespace std;

bool first;
void test() 
{
	if (first == false) 
	{
		first = true;
		cout << "init" << endl;
	}

	cout << "function end." << endl;
}

int main() 
{
	test();
	test();
	test();

	return 0;
}

 

한 번만 실행되는 블럭인데 매번 명시적으로 조건문을 체크해야 한다.

	if (first == false) 
	{
		first = true;
		cout << "init" << endl;
	}

std::call_once

 

C++11에서 제공되는 <mutex>의 std::call_once를 이용하면 특정 함수를 한 번만 호출할 수 있다.

call_once를 사용하면 명시적인 조건문을 사용하지 않아도 된다.

 

아래 코드를 실행해 보자.

std::once_flag 객체를 사용하여 초기화 함수가 한 번만 호출되도록 보장한다.

#include <iostream>
#include <mutex>

using namespace std;

once_flag flag;

void test() 
{
	call_once(flag, []() {
		cout << "init" << endl;
	});

	cout << "function end." << endl;
}

int main() 
{
	test();
	test();
	test();

	return 0;
}

 

그리고 call_once 내부의 블럭을 함수로 변경할 수도 있다.

void init()
{
	cout << "init" << endl;
}

void test()
{
	call_once(flag, init);

	cout << "function end." << endl;
}

 

mutex는 동시성 관련 헤더이며, 여러 스레드에서 동시에 해당 함수를 호출할 때,

특정 함수를 한 번만 호출하도록 보장하기 위해 call_once를 사용한다.

#include <iostream>
#include <mutex>

using namespace std;

once_flag flag;

void init()
{
	cout << "init" << endl;
}

void test()
{
	call_once(flag, init);

	cout << "function end." << endl;
}

int main()
{
	thread t1(test);
	thread t2(test);
	thread t3(test);

	t1.join();
	t2.join();
	t3.join();

	return 0;
}


매개변수 전달

 

call_once를 사용하는 함수에 인자를 전달해야 하는 경우는 람다 함수를 이용하면 된다.

[capture](parameters) -> return_type {
    // 함수 구현
}

 

사용 예시는 다음과 같다.

#include <iostream>
#include <mutex>

using namespace std;

once_flag flag;

void init(int val1, int val2)
{
	cout << "init : " << val1 << ", " << val2 << endl;
}

void test(int val1, int val2)
{
	call_once(flag, [val1, val2]() {
		init(val1, val2);
	});

	cout << "function end." << endl;
}

int main()
{
	thread t1(test, 1, 2);
	thread t2(test, 3, 4);
	thread t3(test, 5, 6);

	t1.join();
	t2.join();
	t3.join();

	return 0;
}

반응형

댓글