Rendezvous: Difference between revisions

Content added Content deleted
(Added Erlang)
Line 295: Line 295:
return 0;
return 0;
}</lang>
}</lang>

=={{header|Erlang}}==
There is no rendezvous in Erlang. To fulfil the task description I have implemented rendezvous with message passing (which is in Erlang). Doing these printers directly with message passing would have been simpler (in Erlang).

<lang Erlang>
-module( rendezvous ).

-export( [task/0] ).

task() ->
Printer_pid = erlang:spawn( fun() -> printer(1, 5) end ),
Reserve_printer_pid = erlang:spawn( fun() -> printer(2, 5) end ),
Monitor_pid = erlang:spawn( fun() -> printer_monitor(Printer_pid, Reserve_printer_pid) end ),
erlang:spawn( fun() -> print(Monitor_pid, humpty_dumpty()) end ),
erlang:spawn( fun() -> print(Monitor_pid, mother_goose()) end ).

humpty_dumpty() ->
["Humpty Dumpty sat on a wall.",
"Humpty Dumpty had a great fall.",
"All the king's horses and all the king's men,",
"Couldn't put Humpty together again."].

mother_goose() ->
["Old Mother Goose,",
"When she wanted to wander,",
"Would ride through the air,",
"On a very fine gander.",
"Jack's mother came in,",
"And caught the goose soon,",
"And mounting its back,",
"Flew up to the moon."].

print( Pid, Lines ) ->
io:fwrite( "Print ~p started~n", [erlang:self()] ),
print( Pid, Lines, infinity ).

print( _Pid, [], _Timeout ) -> ok;
print( Pid, [Line | T], Timeout ) ->
print_line( Pid, Line, Timeout ),
print_line_done(),
print( Pid, T, Timeout ).

print_line( Pid, Line, Timeout ) ->
Pid ! {print, Line, erlang:self()},
receive
{print, started} -> ok
after Timeout -> erlang:throw( timeout )
end.

print_line_done() ->
receive
{printer, ok} -> ok;
{printer, out_of_ink} -> erlang:throw( out_of_ink )
end.

printer( N, 0 ) ->
receive
{print, _Line, Pid} -> Pid ! {printer, out_of_ink}
end,
printer( N, 0 );
printer( N, Ink ) ->
receive
{print, Line, Pid} ->
Pid ! {printer, ok},
io:fwrite( "~p: ", [N] ),
[io:fwrite("~c", [X]) || X <- Line],
io:nl()
end,
printer( N, Ink - 1 ).

printer_monitor( Printer, Reserve ) ->
{Line, Pid} = printer_monitor_get_line(),
Result = printer_monitor_print_line( Printer, Line ),
printer_monitor_reserve( Result, Reserve, Line, Pid ),
printer_monitor( Printer, Reserve ).

printer_monitor_get_line() ->
receive
{print, Line, Pid} ->
Pid ! {print, started},
{Line, Pid}
end.

printer_monitor_print_line( Printer_pid, Line ) ->
Printer_pid ! {print, Line, erlang:self()},
receive
{printer, Result} -> Result
end.

printer_monitor_reserve( ok, _Reserve_pid, _Line, Pid ) -> Pid ! {printer, ok};
printer_monitor_reserve( out_of_ink, Reserve_pid, Line, Pid ) -> Reserve_pid ! {print, Line, Pid}.
</lang>
{{out}}
The first printouts are there to show the identity of the processes that print. It makes it easier to match the exception to one of them and not to some other process.
<pre>
53> rendezvous:task().
Print <0.251.0> started
Print <0.252.0> started
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,

=ERROR REPORT==== 22-Sep-2013::12:09:56 ===
Error in process <0.252.0> with exit value: {{nocatch,out_of_ink},[{rendezvous,print_line_done,0,[{file,"rendezvous.erl"},{line,48}]},{rendezvous,print,3,[{file,"rendezvous.erl"},{line,35}]}]}
</pre>


=={{header|F_Sharp|F#}}==
=={{header|F_Sharp|F#}}==