%%% $Id: prodcons.oz,v 1.0 2002/11/05 12:23:00 dada Exp $ %%% http://dada.perl.it/shootout/ %%% %%% contributed by Isaac Gouy %% Section 11.5 of the Oz Tutorial provides these %% implementations of Event and UnitBufferM and states: %% in Oz, it is very rare to write programs in the %% (traditional) monitor style shown above. In general %% it is very awkward. %% %% There's an extensive treatment of Oz concurrency in %% the book 'Concepts, Techniques, and Models of Computer %% Programming' - find it online with google. %% %% Usage: start from command line with %% ozc -x prodcons.oz -o prodcons.oz.exe %% prodcons.oz.exe 100000 functor import System Application define Produced Consumed class Event from BaseObject prop locking attr f r meth init X in f <- X r <- X end meth put(I) X in lock @r=I|X r<-X end end meth get(?I) X in lock @f=I|X f<-X end {Wait I} end meth wait {self get(_)} end meth notify {self put(unit)} end end class UnitBufferM attr item empty psignal csignal prop locking meth init empty <- true psignal <- {New Event init} csignal <- {New Event init} end meth put(I) X in lock if @empty then item <- I empty <- false X = yes {@csignal notify} else X = no end end if X == no then {@psignal wait} {self put(I)} end end meth get(I) X in lock if {Not @empty} then I = @item empty <- true {@psignal notify} X = yes else X = no end end if X == no then {@csignal wait} {self get(I)} end end end proc {Producer N I B} if N > 0 then {B put(I)} %% {System.showInfo 'Produced '#I} %% just to check synchronization {Producer N-1 I+1 B} else Produced = {NewCell I} end end proc {Consumer N I B} if N > 0 then {B get(I)} %% {System.showInfo 'Consumed '#I} %% just to check synchronization {Consumer N-1 I+1 B} else Consumed = {NewCell I} end end in local Args N UB in [Args] = {Application.getArgs plain} N = {String.toInt Args} UB = {New UnitBufferM init} thread {Producer N 0 UB} end thread {Consumer N 0 UB} end %% Oz is a dataflow language. %% The main thread will wait until logic variables %% Produced and Consumed have been given values {System.showInfo {Access Produced}#' '#{Access Consumed}} end {Application.exit 0} end