C++11 - 블럭 범위를 가진 static 변수 초기화는 스레드 세이프 하다

개요

static 변수의 초기화가 완료할 때까지 다른 스레드는 초기화 처리 앞에서 대기한다.

class singleton {
public:
  static singleton& get_instance()
  {
    static singleton instance; // 이 초기화는 스레드 세이프
    return instance;
  }
};

get_instance 함수를 복수의 스레드에서 호출할 때 singleton 객체 초기화는 하나의 스레드에서만 호출된다.

C++11 이전에는 로컬의 static 변수를 초기화 하는 것이 스레드 세이프하지 않았기 때문에 Double Checked Locking 라는 기법을 사용하였다.


Double Checked Locking

  • static 지역 변수 대신 포인터를 static 멤버 변수로 가진다
  • 포인터가 null 인지 아닌지를 체크하고, null 이라면 lock을 획득한다.
  • null 체크 및lock 취득 사이에 유효한 포인터가 될 가능성이 있기 때문에 lock 취득 후 한번 더 null 체크를 하고 null 이면 초기화를 한다

이 글은 2017-02-14에 작성되었습니다.