sicp.io
3.4.2 · 직렬 실행과 배제

serializer는 한 상태 전이가 끝난 뒤 다음 전이를 시작하게 한다.

잠금 셀과 test-and-set 경계는 겹친 진입을 거부하고 serializer는 공유 상태를 바꾸는 프로시저를 같은 잠금으로 감쌉니다.

생각해 볼 질문

한 갱신이 상태를 읽은 뒤 다른 갱신이 끝나고 나서야 쓰는 일을 막으려면 무엇을 보호해야 할까요?

  • test-and-set!이 이전 잠금 상태를 반환한다고 읽기
  • 획득 실패와 해제 뒤 재시도를 구분하기
  • 공유 잠금 하나로 상태 변경 프로시저 감싸기
  • 오래된 읽기의 갱신 손실과 직렬화된 유한 실행 비교하기

잠금은 단일 셀 변경 가능 리스트입니다. test-and-set!은 셀이 이미 참이었는지 보고하며, 그렇지 않다면 셀을 참으로 변경하고 이전의 거짓 상태를 보고합니다. 따라서 첫 번째 획득은 성공하고, 겹친 시도는 실패하며, clear! 이후의 재시도는 성공합니다. 이 브라우저 프로그램은 SICP의 원자적 구현 경계를 유한 스케줄의 이름 붙은 단일 연산으로 모델링합니다.

make-serializer는 공유 잠금을 받아 프로시저 래퍼를 반환합니다. 래퍼는 상태 변경 프로시저를 호출하기 전에 획득하고, 결과를 받은 뒤 해제합니다. 제공된 유한 스케줄에서는 출금이 balance를 읽기 전에 직렬화된 입금이 완료되므로, 최종값 90에 두 갱신이 모두 유지됩니다. 이 수업은 이 정확한 스케줄과 최종 상태를 기록합니다.

SICP 코드UTF-8 468 / 1,048,576바이트
예제
결과
출력
진단
실행 추적0 / 0 개 이벤트
    실행은 브라우저 안에서 이루어지며 프로그램 결과와 실행 추적을 보여줍니다.
    예상 결과

    첫 번째 프로그램은 (#t #f #t #t)를 반환합니다. 두 번째 프로그램은 (80 110 90 90 #f)를 반환합니다.

    실행 추적에서 볼 점

    첫 번째 실행에서는 clear!로 구분되는 두 번의 set-car! 전이를 찾고, 아무런 변경도 수행하지 않는 겹친 호출을 구분하세요. 두 번째 실행에서는 lost-update 내부의 두 오래된 읽기를, 잠금을 획득하고 한 번의 balance 대입을 마친 뒤 해제하고 나서야 다음 래퍼가 읽도록 허용하는 직렬화된 래퍼와 비교해 보세요. 고정 제한 실행 흐름은 이러한 명시적인 순차 스케줄만을 설명합니다.

    직접 해보기

    프로그램을 수정하고 결과를 비교해 보세요.

    serialized-deposit 직전에 공유 잠금을 참으로 설정하세요. 그 결과와 balance를 예측한 다음, 잠금을 해제하고 입금을 다시 호출해 보세요.

    힌트 보기

    busy 상태의 래퍼는 보호 대상 프로시저를 호출하지 않습니다. clear! 이후에는 동일한 래퍼가 잠금을 획득하고 갱신을 수행할 수 있습니다.

    이 수업 완료하기

    이 장의 총 21개 수업 중 0개 완료0%