두 스레드 A와 B가 공유 변수 count를 각각 1씩 올립니다. 결과는 당연히 2여야 하지만, 실행 순서에 따라 1이 나오기도 합니다. 버튼을 눌러 두 스레드의 실행 순서를 직접 정해 보세요.
두 스레드가 count++를 세 단계로 나누어 실행하며 값이 사라지는 과정을 보여 주는 시뮬레이터
빠르게 보기
직접 순서 정하기: 각 스레드 아래 버튼을 원하는 순서로 누르세요
스레드 A
A의 레지스터-
공유 메모리
0
count스레드 B
B의 레지스터-
노란색 줄은 그 스레드가 다음에 실행할 명령입니다. [A와 B를 번갈아 실행]을 누르면 값이 사라지는 경우를 바로 볼 수 있습니다.
count++는 한 번에 끝나지 않습니다
코드에서는 한 줄이지만, CPU는 count++를 세 단계로 나눠 실행합니다. 메모리에서 값을 읽고, 레지스터에서 1을 더하고, 결과를 메모리에 다시 씁니다. 운영체제는 이 세 단계 중 어디서든 실행 중인 스레드를 바꿀 수 있습니다.
A가 0을 읽은 직후 B로 바뀌면, B도 0을 읽습니다. 두 스레드는 각자 1을 만들어 메모리에 쓰고, 나중에 쓴 값이 먼저 쓴 값을 덮어씁니다. 증가 한 번이 흔적 없이 사라집니다. 이처럼 실행 순서에 따라 결과가 달라지는 상황을 레이스 컨디션이라고 합니다.
임계 구역
공유 데이터를 읽고 쓰는 코드 구간을 임계 구역이라고 합니다. 한 번에 한 스레드만 임계 구역에 들어가게 막으면 세 단계가 중간에 끊기지 않아 결과가 항상 2가 됩니다. 이렇게 막는 도구가 뮤텍스와 세마포어입니다.