멀티코어와 동기화
위 코드는 CAS(&p, 기대값, 새 값)를 사용하여 공유 변수 counter를 2배로 만들고 있다. CAS가 실패하여 루프를 다시 도는 경우는 언제인가?
int old, new;
do {
old = counter;
new = old * 2;
} while (!CAS(&counter, old, new));
- Acounter의 값이 0일 때
- Bold를 읽고 나서 CAS를 실행하기까지의 사이에 다른 스레드가 counter를 바꾸었을 때
- Cnew의 값이 old보다 클 때
정답과 해설 보기
정답: B. old를 읽고 나서 CAS를 실행하기까지의 사이에 다른 스레드가 counter를 바꾸었을 때
CAS는 counter가 읽었을 때의 old 그대로라면 새 값을 씁니다. 그 사이에 다른 스레드가 값을 바꾸었다면, 손에 든 new는 오래된 값을 바탕으로 계산한 것이므로 쓰지 않고 실패를 반환합니다. 루프는 최신 값을 다시 읽어 계산을 재시도합니다. 덧셈만이라면 fetch-and-add로 충분하지만, 2배로 만드는 것과 같은 임의의 갱신도 이 형태로 불가분하게 수행할 수 있습니다.
- A. 0이어도 다른 곳에서 바뀌지 않았다면 성공합니다.
- B. 맞습니다. 오래된 값을 바탕으로 한 계산을 버리고 재시도합니다.
- C. 값의 대소는 실패 조건이 아닙니다.