더북(TheBook)

실제로 게임 서버를 개발할 때도 이러한 현상을 볼 수 있습니다. 잠금을 한 후 디바이스 타임을 일으키는 코드를 넣음으로써 서버에 심각한 직렬 병목이 발생해서 서비스가 원활하지 못하게 됩니다.

이때는 ReadFromDisk(X)를 하기 전에 lock(A)를 하지 말아야 합니다. ReadFromDisk()를 한 후에 lock(A)를 할지 말지 결정해야 합니다. 단 lock(A)를 하지 않을 동안 A가 보호하는 데이터들에 다른 스레드가 뭔가 변경을 가할 수 있습니다. 따라서 lock(A) 후에는 그 전의 상태가 바뀌었음을 다시 한 번 체크해야 합니다. 다음 코드를 봅시다.

X = A.GetFoo();
unlock(A)         // ➊
ReadFromDisk(X)
lock(A)
X.Something();    // ➋

에서 X를 액세스합니다. 하지만 X는 이미 사라진 객체일 가능성이 있습니다. unlock(A)가 실행된 후에 다른 스레드가 A를 변화시켰기 때문입니다. 이때는 X를 다시 얻어 오던지 해서 정상화를 해 주어야 합니다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.