Search code examples
erlangmessage-passing

Erlang: How to receive a message only from a specific sender?


In Erlang, how can I receive a message sent from a specific pid?


Solution

  • Here are a couple of ways:

    1) Send the target process a secret code, which it can send back with all its messages:

    -module(my).
    -compile(export_all).
    
    worker(TargetPid, Msg, SecretId) ->
         TargetPid ! {Msg, SecretId}.
    
    get_msg(SecretId) ->
        receive
            {Msg, SecretId} -> Msg
        end. 
    
    test() ->
        SecretId = "A1!cd!",
        spawn(my, worker, [self(), hello, "Xy*d1"]),
        spawn(my, worker, [self(), goodbye, SecretId]),
    
        io:format("~w~n", [get_msg(SecretId)]).
    

    In the shell:

    6> c(my).    
    my.erl:2: Warning: export_all flag enabled - all functions will be exported
    {ok,my}
    
    7> my:test().
    goodbye
    ok
    
    8> 
    

    2) Instead of matching against the secret code in the receive clause, have the target process send a message tagged with its Pid:

    -module(my).
    -compile(export_all).
    
    get_msg(TargetPid) ->
        receive
            {Msg, TargetPid} -> Msg
        end. 
    
    worker(TargetPid, Msg) ->
         TargetPid ! {Msg, self()}.
    
    test() ->
        spawn(my, worker, [self(), hello]),
        Pid = spawn(my, worker, [self(), goodbye]),
    
        io:format("~w~n", [get_msg(Pid)]).
    

    In the shell:

    3> c(my).
    my.erl:2: Warning: export_all flag enabled - all functions will be exported
    {ok,my}
    
    4> my:test().
    goodbye
    ok
    
    5>