[erlang-questions] [LONG] How to make synchronous message passing

Vlad Dumitrescu <>
Tue Oct 2 14:20:26 CEST 2007


Hi,

One way could be to create a unique reference for each call and send
it together with the request. When waiting for the reply, selectively
receive with the reference as parameter.

Something in the lines of:

 synchro(Pid, Message) ->
     Ref = make_ref(),
     Pid ! {self(), Ref, Message},
     receive
         {Ref, Reply} ->
             Reply
     end.

Instead of Pid ! Reply, call

  reply(Pid, Ref, Reply) ->
     Pid ! {Ref, Reply).

best regards,
Vlad

On 10/2/07, ZeD <> wrote:
> Hi all.
>
> For my studies, I'm trying to implement a way to let me do synchronous
> message passing, but I found some problems.
>
> ATM I'm trying starting from a simple idea: make an asynchronous
> communication, but wait for a reply
>
> synchro(Pid, Message) ->
>     Pid ! {self(), Message},
>     receive
>         Reply ->
>             Reply
>     end.
>
> For simple communications it works flawlessly, but I encountered problems
> when I tried to make talk together a net of pairs (processes which are
> istantiations of the same function f)
>
> f(Name) ->
>   receive
>     {Sender, {do, Pid, Do}} ->
>         Sender ! synchro(Pid, Do),
>         f(Name);
>     {Sender, {ask, Pid}} ->
>        Sender ! synchro(Pid, name),
>        f(Name);
>     {Sender, name} ->
>        Sender ! Name,
>        f(Name)
>   end.
>
> for istance, let's say a process P want to make Q talk to P himself (for
> some reason). So, we shoud write
>
> synchro(P, {do, Q, {ask, P}}).
>
> but, instead of the Name of P, all I have is "{P, name}", because the
> synchro function taked the "wrong" reply (as it wasn't a reply to a
> communication, just another message.
>
> So I tried to restrict the reply on a specific form:
>
> synchro2(Pid, Message) ->
>     Pid ! {self(), Message},
>     receive
>         {Pid, Message, Reply} ->
>             Reply
>     end.
>
> f2(Name) ->
>   receive
>     {Sender, {do, Pid, Do}=M} ->
>         Sender ! {self(), M, synchro(Pid, Do)},
>         f2(Name);
>     {Sender, {ask, Pid}=M} ->
>        Sender ! {self(), M, synchro(Pid, name)},
>        f2(Name);
>     {Sender, name} ->
>        Sender ! {self(), name, Name},
>        f2(Name)
>   end.
>
> but all I got is a blocked session, because while P wait for a reply from Q,
> he got instead another query, and lost it, so Q wait for P and P for Q.
>
> So, how can I implement an "atomic" (?) synchronous message passing? I tried
> to "collect" all the non-matching messages in synchro, and resend them to
> self(), but nothing changed.
>
> --
> Under construction
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://www.erlang.org/mailman/listinfo/erlang-questions
>



More information about the erlang-questions mailing list