반응형
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;
}
반응형
'개발 > C, C++' 카테고리의 다른 글
C++ - friend로 private 멤버 출력하기 (Printing private members using friend) (0) | 2024.02.13 |
---|---|
C++ - atomic으로 원자적 연산 처리하기 (vs mutex) (0) | 2024.01.26 |
C++ - 정수를 IP로 변환하기 (IP Converter for IPv4, IPv6, Integer, in_addr, in6_addr) (1) | 2023.11.28 |
C++ - 연산자 오버로딩을 이용하여 구조체 출력하기 (cout with overloading) (0) | 2023.11.22 |
C++ - map, functional로 함수 호출하기 (0) | 2023.11.22 |
댓글