sicp-ex-3.39



<< Previous exercise (3.38) | Index | Next exercise (3.40) >>


adams

  121 - P2 then P1
  101 - P1 then P2
  100 - P1 gets x^2 to be 100.  Then P2 sets x after which P1 sets x to be 100.
 110 cannot be done since x^2 will not be interleaved with P2 which means the value of x will be the same meaning it is either 100 or 121.
 11 cannot be done since once P2 starts, P1 cannot finish until P2 is done.

leafac

I believe the above is wrong and

110: P2 changes x from 10 to 11 between the two times that P1 accesses the value of x during the evaluation of (* x x).

is indeed possible. The serializer doesn't protect P1 at all.


atupal

@leafac I think adams is right, as "(s (lambda () (* x x))))" protected the (* x x) from interleaved, P2 can not changes x between the two times that P1 accessed the x.


karthikk

None of the above is correct!! Actually the right solution is 121, 100, 101 AND 11. adams has the right reasons for the first three. However you can also get 11: Lets label the 3 processes involved: S1: calculation of x^2, S2: setting x to calculated value of x^2; R1: acquisition of value of x and setting it to x+1. Now here is what can happen: S1: acquires the mutex and calculates the value of x^2 i.e. 100, now it releases the mutex. At this point R1 acquires the mutex and calculates a value of 11 BUT before it can set the value to 11, S2 occurs (nothing barring it from occuring concurrently with R1) and therefore R1 gets to set the final value of x, i.e. 11. You can convince yourselves by running the following simulation:

  
 (define (run-many-times in-test num) 
   (define (run-test numtimes output) 
     (let ((m (in-test))) 
       (cond ((= 0 numtimes) output) 
             ((memq m output) (run-test (- numtimes 1) output)) 
             (true (run-test (- numtimes 1) (cons m output)))))) 
   (run-test num '())) 
  
 (define (test-2) 
   (define x 10) 
   (define s (make-serializer)) 
   (parallel-execute (lambda () (set! x ((s (lambda () (* x x)))))) 
                     (s (lambda () (set! x (+ x 1))))) 
   x) 
  
 (display (run-many-times test-2 10000)) 
  
 ;;Output will be (11 100 101 121) in some order