Rendezvous: Difference between revisions

Added Oz.
m (Fixed lang tags.)
(Added Oz.)
Line 221:
Return -1
}</lang>
 
=={{header|Oz}}==
Oz does not have a rendezvous mechanism, but the task description lends itself to synchronous [http://c2.com/cgi/wiki?ActiveObject active objects]. We show how to implement this in Oz and then discuss the differences to the rendezvous model.
 
First a simple printer class whose definition is completely orthogonal to multithreading issues:
<lang oz>declare
class Printer
attr ink:5
feat id backup
meth init(id:ID backup:Backup<=unit)
self.id = ID
self.backup = Backup
end
meth print(Line)=Msg
if @ink == 0 then
if self.backup == unit then
raise outOfInk end
else
{self.backup Msg}
end
else
{System.printInfo self.id#": "}
for C in Line do
{System.printInfo [C]}
end
{System.printInfo "\n"}
ink := @ink - 1
end
end
end</lang>
Note how requeuing the task simply becomes delegation to a different object.
 
Active object are not a predefined abstraction in Oz. But due to Oz' first-class object messages, we can easily define it using ports and streams (many-to-one message passing):
<lang oz> fun {NewActiveSync Class Init}
Obj = {New Class Init}
MsgPort
in
thread MsgStream in
{NewPort ?MsgStream ?MsgPort}
for Msg#Sync in MsgStream do
try
{Obj Msg}
Sync = unit
catch E then
Sync = {Value.failed E}
end
end
end
proc {$ Msg}
Sync = {Port.sendRecv MsgPort Msg}
in
{Wait Sync}
end
end</lang>
This functions takes a class and an initialization message and returns a procedure. When called, this procedure will send messages to the new object in a new thread and then wait for the <code>Sync</code> variable to become bound. Exceptions are propagated using [http://www.mozart-oz.org/home/doc/base/node13.html#label696 failed values].
 
This works because a unary procedure is syntactically indistinguishable from an object in Oz.
 
With this new abstraction we can create the two printers and execute both print tasks in their own thread:
<lang oz> Main = {NewActiveSync Printer init(id:1 backup:Reserve)}
Reserve = {NewActiveSync Printer init(id:2)}
in
%% task Humpty Dumpty
thread
try
{Main print("Humpty Dumpty sat on a wall.")}
{Main print("Humpty Dumpty had a great fall.")}
{Main print("All the king's horses and all the king's men")}
{Main print("Couldn't put Humpty together again.")}
catch outOfInk then
{System.showInfo " Humpty Dumpty out of ink!"}
end
end
 
%% task Mother Goose
thread
try
{Main print("Old Mother Goose")}
{Main print("When she wanted to wander,")}
{Main print("Would ride through the air")}
{Main print("On a very fine gander.")}
{Main print("Jack's mother came in,")}
{Main print("And caught the goose soon,")}
{Main print("And mounting its back,")}
{Main print("Flew up to the moon.")}
catch outOfInk then
{System.showInfo " Mother Goose out of ink!"}
end
end</lang>
 
Example output:
<pre>
1: Humpty Dumpty sat on a wall.
1: Old Mother Goose
1: Humpty Dumpty had a great fall.
1: When she wanted to wander,
1: All the king's horses and all the king's men
2: Would ride through the air
2: Couldn't put Humpty together again.
2: On a very fine gander.
2: Jack's mother came in,
2: And caught the goose soon,
Mother Goose out of ink!
</pre>
 
'''Comparison to Ada'''
 
What is called an "entry point" in Ada, is a method in our implementation.
 
We cannot limit the waiting time. This could be implemented in the NewActiveSync function, but it is not needed in the example task.
 
The callee task accepts rendezvous requests to the same entry point from multiple caller tasks. Similarly, the active object in Oz is designed to accept messages from different threads. To implement "rendezvous to different entry points", we simply add public methods to the Printer class.
 
The callee in ADA accepts one rendezvous at a time. The active object in Oz reads one message at a time from the stream.
 
Messages cannot be requeued in the given implementation. But we can delegate to a different active object which has the same effect, at least for the example given.
 
Like in the rendezvous mechanism, parameters are not marshalled. This is because sharing immutable data between threads is safe.
In contrast to ADA, the parameters are buffered until the printer becomes ready. But with a synchronous communication mechanism, this should not cause problems.
 
=={{header|Tcl}}==
Anonymous user