Thread-safe 와 메모리 장벽
Thread-safe
멀티스레드 환경에서 여러 스레드가 동시에 하나의 객체 및 변수(공유 자원)에 접근할 때, 의도한 대로 동작하는 것을 말한다.
이러한 상황을 “Thead-safe하다” 라고 표현한다.
Thread-safe 만드는법
Thread-safe하기 위해서는 공유 자원에 접근하는 임계영역(critical section)을 동기화 기법으로 제어해줘야 한다.
이를 ‘상호배제’라고 한다.
동기화 기법으로는 Mutex나 Semaphore 등이 있다.
critical section
critical section 을 설정한 구간은 한번에 하나의 스레드 에서만 사용가능하다.
여러 스레드를 사용하는 환경에서 critical section 에 어떤 스레드가 먼저 접근하여 사용하는경우 다른 스레드가 접근하지 못하게 한다.
Reentrant
Reentrant는 재진입성이라는 의미로, 어떤 함수가 Reentrant하다는 것은 여러 스레드가 동시에 접근해도 언제나 같은 실행 결과를 보장한다는 의미이다.
이를 만족하기 위해서 해당 서브루틴에서는 공유자원을 사용하지 않으면 된다.
따라서, Reentrant하다면 Thread-safe하지만 그 역은 성립하지 않는다.
위의 Reentrant 는 메모리 가시성과 메모리 장벽과도 관련이 있다.
메모리 가시성(Memory Visiblity)
Thread에서 변경한 특정 메모리의 값이, 다른 Thread에서 제대로 읽어지는지가 라고 할 수 있다.
멀티 스레드를 다룰때 이런 문제가 생기곤 하는데, 메모리 가시성 문제가 발생하는 이유는 CPU의 메모리 아키텍쳐, 즉 레지스터와 캐쉬의 존재 때문이다.
두번째 이유는 컴파일러는 프로그램이 최대한 빠르게 실행될 수 있도록 코어(CPU)의 레지스터와 캐쉬를 사용하도록 최적화 하기 때문이다.
해결법
한 코어(CPU)에서의 값 변경을 여러 코어(CPU)가 공유하는 메인 메모리로 반영하는 작업을 적절히 수행해야 메모리 가시성을 유지할 수 있게된다
레지스터나 캐시의 값을 메인 메모리에 반영하는것은 느리기 때문에 따라서 적절히 필요한 시점에만 메인 메모리로 반영하도록 하는 것이 필요하다.
그래서 등장하는 개념이 바로 메모리 장벽(Memory Barrier) 이다.
메모리 장벽(Memory Barrier)
메모리 장벽을 만나기 면, 그전까지 코어(CPU)의 레지스터나 캐쉬값의 변경을 메인 메모리로 반영하는 것이라고 할 수 있다.
메인 메모리로 Flush 한다고도 하는데, 이렇게 함으로써 다른 코어(CPU)에서 변경된 값을 읽을 수 있도록 하는 것이다.
참고 : http://blog.naver.com/PostView.nhn?blogId=jjoommnn&logNo=130037479493
https://igotit.tistory.com/entry/Critical-Section-%ED%81%AC%EB%A6%AC%ED%8B%B0%EC%BB%AC-%EC%84%B9%EC%85%98
https://github.com/WeareSoft/tech-interview/blob/master/contents/os.md#thread-safe