CafeM0ca

[C++] std::call_once, std::once_flag 본문

Programming/C++

[C++] std::call_once, std::once_flag

M0ca 2018. 9. 16. 17:36
반응형

std::call_once는 callable을 등록할 수 있다.

std::once_flag는 하나의 등록된 함수만이 호출될 수 있음을 보장한다.

둘 다 <mutex>에 있다.


std::call_once

- 오직 하나의 함수가 한 번만 수행됨. 어느 함수가 선택될지는 정의되지 않음. 선택된 함수는 std::call_once 호출과 동일한 스레드에서 실행

- 성공적으로 완료되기 전까지 어떤 호출도 리턴되지 않음.

- 예외로 종료시 caller에게 전파. 이에 따라 새로운 함수가 선택되고 실행됨.



#include <iostream>
#include <thread>
#include <mutex>
std::once_flag onceFlag;

void do_once() {
    std::call_once(onceFlag, []() { std::cout << "Only once." << std::endl; });
}
int main()
{
    std::cout << std::endl;

    std::thread t1(do_once);
    std::thread t2(do_once);
    std::thread t3(do_once);
    std::thread t4(do_once);
     
    t1.join();
    t2.join();
    t3.join();
    t4.join();

    return 0;
}


실행 결과

Only once.



분명 do_once함수가 4개의 쓰레드에 의하여 4번 호출되어야하는데 단 한번만 실행되었다.



이것을 singleton에 적용하면 하나의 instance가 생성됨을 보장할 수 있다.

/*

class MySingleton {
private:
    static once_flag initInstanceFlag;
    static MySingleton* instance;
    MySingleton() = default;
    ~MySingleton() = default;

public:
    MySingleton(const MySingleton&) = delete;
    MySingleton& operator=(const MySingleton&) = delete;
    static MySingleton* getInstance() {
        call_once(initInstanceFlag, MySingleton::initSingleton);
        return instance;
    }
    static void initSingleton() {
        instance = new MySingleton();
    }
};
*/

반응형
Comments