해당 포스트는 쉬운코드님의 유튜브 영상을 정리한 내용입니다.
같은 프로세스에 속하는 쓰레드들은 힙 영역을 공유하기 때문에, 힙 영역의 데이터를 여러 쓰레드들이 동시에 접근하면 데이터 값이 예상과 다르게 바뀔 수 있다.
이를 막기 위해 임계 영역을 만들어 상호 배제한다.
경쟁 조건은 서로 다른 프로세스 간에도 발생할 수 있다.
서로 다른 프로세스의 경우에는 기본적으로 메모리 영역을 공유하지 않지만, 공유 메모리 영역을 만들고 여러 프로세스를 해당 메모리 영역에 매칭시키면, 쓰레드들처럼 프로세스들도 같은 메모리 공간에 접근 가능하기 때문에 경쟁 조건이 발생할 수 있다.
state++; 가 CPU에서 어떻게 실행되는지를 아는 것이 중요하다!
T1에서 state++ 수행 중에 STORE R1 to STATE 연산을 하기 전에 컨텍스트 스위칭이 일어난다면, 아직 state는 변하지 않았기 때문에 증가 연산이 중복되어 씹힌다.
하나의 쓰레드에서 언제 컨텍스트 스위칭이 일어나느냐에 따라서 결과가 달라진다.
예제는 싱글 코어지만 듀얼 코어 등에서도 충분히 일어날 수 있는 일이다.
이를 race condition이라 한다.
여러 프로세스 / 쓰레드가 동시에 같은 데이터를 조작할 때 타이밍이나 접근 순서에 따라 결과가 달라질 수 있는 상황
여러 프로세스 / 쓰레드를 동시에 실행해도 공유 데이터의 일관성을 유지하는 것
3가지 조건을 모두 만족해야 critical section 문제의 해결책이 될 수 있다.
자바에서 기본적으로 제공하는 클래스도 모두 Thread safe한 것은 아니다. 문서를 잘 읽어야 한다.
파이썬에는 cachetools라는 라이브러리로 로컬 캐싱을 사용한다.
이 cachetools에서 제공하는 캐시가 쓰레드 세이프하게 동작하기 위해서는 캐시 선언하면서 파라미터에 Lock을 넣어줘야 하는데, 문서나 예제 코드들에서는 굳이 락을 넣어주지 않아 실수할 여지가 존재한다. 디폴트가 쓰레드 세이프하지 않기 때문
이로 인해 캐싱 데이터가 만료되거나 삭제될 때 에러가 발생할 수 있다.