2008년 07월 16일
SICP Exercise 연습문제 3.39
이 문제는 프로시저 일부만을 줄세우기 할 때 어떻게 될지 확인하는 문제입니다.
처음에 저는 100, 121, 101을 생각하였습니다.
하지만 DrScheme로 돌린 결과는 하나가 더 추가된 결과를 보여주었습니다.

보시면 값으로 121, 101, 11, 100이 나옵니다.
왜 11이 나오는지 생각해보았습니다.

위의 코드에서 윗 부분의 (lambda () (* x x))를 A로, (set! x A)를 B로,
밑 부분의 (lambda () (set! x (+ x 1)))를 C로 하겠습니다.
make-serializer를 쓰면 거기에 적용하는 프로시저는 순서를 따집니다.
따라서 A와 C는 같이 동작될 수 없습니다.
그리고 A가 실행되어야 B가 실행되므로 B는 A보다 앞서거나 동시에 실행될 수 없습니다.
이 규칙에 따라 그림을 그려보았습니다.

위 그림의 규칙은 다음과 같습니다.
1. 시간은 위에서 아래로 흐른다.
2. 같은 세로줄에 있는 것은 make-serializer로 묶여진 프로시저.
3. 같은 가로줄에 있는 것은 같은 시간에 작동하는 프로시저.
그리하여 만들어보니 위의 그림처럼 총 네가지가 나왔습니다.
1. A를 실행하여 x로 10을 받아 제곱을 하여 100을 만들어 임시로 저장하고 있습니다.
그 다음 C를 실행하여 x로 10을 받아(왜냐하면 아직 B가 실행되지 않았으므로...)
이에 1을 더하여 11로 만든 후 x에 저장합니다.
마지막으로 B를 실행하여 A가 만든 100을 x에 저장합니다.
따라서 최종 결과 : x = 100
2. A를 실행하여 x로 10을 받아 제곱을 하여 100을 만들어 임시로 저장하고 있습니다.
그 다음 C를 실행하여 x로 10을 받습니다.
하지만 x에 1을 더하는 도중에 B가 실행되어 x에 100을 저장합니다.
그 후 x는 10에 1을 더한 11을 x에 저장합니다.
따라서 최종 결과 : x = 11
3. A를 실행하여 x로 10을 받아 제곱을 하여 100을 만들어 임시로 저장하고 있습니다.
그 다음 B를 실행하여 x에 100을 저장합니다.
마지막으로 C를 실행하여 x에 1을 더한 101을 저장합니다.
따라서 최종 결과 : x = 101
4. C를 실행하여 x로 10을 받아 1을 더하여 x에 11을 저장합니다.
그리고 A를 실행하여 제곱을 한 후 B를 실행하여 121을 x에 저장합니다.
따라서 최종 결과 : x = 121
이렇게 그림을 그려 생각을 해보니 훨씬 쉽게 이해되고 추리할 수 있었습니다.^^
번외의 얘기이지만 과연 결과의 분포를 조사해보았습니다.

121이 75%로 매우 많습니다.^^
하지만 11과 100은 그 수가 매우 미미하네요.
그렇다 할지라도 이런 버그 하나가 시스템을 망칠 수 있으니
막을 수 있는 것이라면 막아서 사고를 방지해야겠죠.^^;;
참조
해럴드 애빌슨, 김재우 역, <컴퓨터 프로그램의 구조와 해석>, 인사이트, 2007, pp. 397
(require (planet "sicp-concurrency.ss" ("dyoo" "sicp-concurrency.plt" 1 1)))
(define (exercise_3_39)
(define x 10)
(define s (make-serializer))
(parallel-execute (lambda () (set! x ((s (lambda () (* x x))))))
(s (lambda () (set! x (+ x 1)))))
x)
; execute
(define (iter-pro n)
(define (iter k)
(if (<= k n)
(begin (display (exercise_3_39))
(display " ")
(if (= (remainder k 14) 0)
(newline))
(iter (+ k 1)))))
(iter 1))
(iter-pro (* 14 100))
# by | 2008/07/16 20:48 | in OCW | 트랙백 | 덧글(0)









☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]