Concurrent Futures

Andreas Raab andreas.raab at gmx.de
Sun Oct 28 06:38:15 UTC 2007


Ralph Johnson wrote:
> If E was automatically free from deadlock, why was this solution so complex?

Because it's trying to illustrate three three issues at once (security, 
capabilities, concurrency) and consequently fails to illustrate either 
one very well :-(

It is trivial to solve this problem via event-loop concurrency though. 
Consider a class Table with operations "grabLeftFork:", "grabRightFork:" 
(which take a seat index as argument and return the fork or nil). You 
can now implement the dining philosophers "Croquet style" as follows:

Philosopher>>eat
   "Start eating"
   | leftForkPromise rightForkPromise |

   "Try to aquire the left fork first"
   leftForkPromise := table future grabLeftFork: seat.
   leftForkPromise whenResolved:[:leftFork|

     "If we couldn't get the left fork, we need to decide
     what to do. Simply retry later but use a random amount
     of time to avoid live-lock"
     leftFork ifNil:[^(self future: self randomMSecs) eat].

     rightForkPromise := table future grabRightFork: seat.
     rightForkPromise whenResolved:[:rightFork|

       rightFork ifNil:[
         "Same as before, but return the fork first"
         table future returnLeftFork: seat.
         ^(self future self randomMSecs) eat "still hungry"
       ] ifNotNil:[
         "We got both forks, eat"
         state := #eating.

         "And return the forks when time is up"
         ^(self future: self timeToEat)
            returnFork: leftFork and: rightFork
       ].
     ].
   ].

Note that there is no wait anywhere in the above - the only thing that 
exists are #future sends that schedule messages to be executed at some 
point later. Because of this, the philosopher never really "waits" for 
anything; he will happily keep thinking (or grumbling ;-) until he 
obtains the forks. Even *while* he is eating one could schedule an 
emergency request to "drop those forks" if that were necessary.

Cheers,
   - Andreas



More information about the Squeak-dev mailing list