동기화
3에 1을 더하고 2배를 했는데, 왜 6이 될까?
문장 하나, 걸음 셋
변수 고치기는 세 걸음입니다
TOTAL = TOTAL + 1은 한 줄이지만 컴퓨터는 세 걸음으로 실행합니다. 변수의 값을 가져오고(fetch), 계산하고, 결과를 변수에 저장합니다(store).
TOTAL은 태스크 여럿이 함께 쓰는 변수이고 처음 값은 3입니다. 이 강의가 따르는 교재의 예입니다.
차례대로
한쪽이 끝난 뒤라면 8
태스크 A는 TOTAL에 1을 더하고, 태스크 B는 TOTAL을 2배로 만듭니다. A의 세 걸음이 다 끝난 뒤에 B가 시작하면 3은 4가 되고, 4는 8이 됩니다.
B의 문장은 TOTAL = 2 * TOTAL입니다. 눈금에 적힌 글은 그 걸음에서 한 일입니다.
엇갈리면
걸음이 섞이면 6
이번에는 A가 저장하기 전에 B가 값을 가져갑니다. 둘 다 3을 가져갔으므로 A는 4를, B는 6을 저장합니다. 나중에 저장한 6이 4를 덮어써서 A의 더하기가 사라집니다.
두 태스크의 문장은 그대로입니다. 걸음이 섞인 순서만 달라졌습니다.
경쟁 조건
순서에 따라 답이 넷
같은 두 문장인데 실행 순서에 따라 8, 7, 6, 4가 다 나올 수 있습니다. 이렇게 실행 순서에 따라 결과가 달라지는 상황을 경쟁 조건(race condition)이라고 합니다.
경쟁 상태라고도 부릅니다. 앞의 두 카드가 이 표의 첫째 줄과 셋째 줄입니다.
경쟁 동기화
한 번에 하나만 들여보냅니다
태스크들의 실행 순서를 제어하는 장치를 동기화(synchronization)라고 합니다. 자원을 한 번에 한 태스크만 쓰게 하는 것이 경쟁 동기화(competition synchronization)이고, 그 방법이 상호 배제(mutual exclusion)입니다.
A가 세 걸음을 마칠 때까지 B가 TOTAL에 손대지 못하면 걸음이 섞이지 않습니다.
협력 동기화
상대의 일이 끝나기를 기다립니다
동기화에는 한 가지가 더 있습니다. 한 태스크가 다른 태스크의 어떤 일이 끝날 때까지 기다려야 하는 경우입니다. 이것이 협력 동기화(cooperation synchronization)입니다. 값을 만드는 생산자와 가져다 쓰는 소비자가 대표적인 예입니다.
버퍼(buffer)는 값을 잠시 담아 두는 곳입니다. 생산자·소비자 문제(producer-consumer problem)는 5편에서 자세히 봅니다.
생존성과 교착 상태
서로 기다리다 둘 다 멈춥니다
프로그램 단위가 결국 실행을 끝낸다는 성질을 생존성(liveness)이라고 합니다. 태스크를 기다리게 하면 이 성질을 잃기 쉽습니다. 모든 태스크가 생존성을 잃은 상태가 교착 상태(deadlock)입니다.
그림은 예시입니다. A는 자원 2가, B는 자원 1이 풀리기를 기다리는데 둘 다 자기가 쥔 것을 놓지 않습니다.
다음 편