Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reference vs pid?

Tags:

erlang

I'm not entirely sure the differences between the PID and Reference and when to use which.

If I were to spawn a new process with spawn/1 pid. I can kill it with the PID no? Why would I need a reference?

Likewise I see monitor/1 receiving a message with a ref and pid number.

Thanks!

like image 938
mythicalprogrammer Avatar asked Nov 19 '14 19:11

mythicalprogrammer


2 Answers

Pid is process identifier. You can get one when you create new process with spawn, or you can get Pid of yourself with self(). It allows you to interact with given process. Especially send messages to it by Pid ! Message. And some other stuff, like killing it explicitly (should not do) or obtaining some process information with erlang:process_info.

And you can create relations between process with erlang:link(Pid) and erlang:monitor(process, Pid) (that's between Pid process, and process execution this function). In short, it gives you "notifications" when another process dies.

Reference is just almost unique value (of different type). One might say, that it gives you some reference to here and now, which you could recognize later. For example, if we are sending a message to another process, and we expect a response, we would like to make sure, that the message we will receive is associated to our request, and not just any message from someone else. The easiest way to do it is to tag the message with a unique value, and wait until a response with exactly the same tag.

  Tag = make_ref(),
  Pid ! {Tag, Message},
  receive 
     {Tag, Response} ->
         ....

In this code, with use of pattern matching, we make sure that (we wait in receive until) Response is exactly for the Message we sent. No matter other messages from other processes. This is the most common use of reference you can encounter.

And now back to monitor. When calling Ref = monitor(process, Pid) we make this special connection with Pid process. Ref that is returned is just some unique reference, that we could use to demonitor this process. That is all.

One might ask, if we are able to create monitor with Pid, why do we need Ref for demonitoring? Couldn't we just use Pid again. In theory we could, but monitors are implemented in such a way, that multiple monitors could be established between two same processes. So when demonitoring, we have to remove only one of such connections. It is done in this way to make monitoring more transparent. If you have library of function that's creating and removing one monitor, you would not like to interfere with other libraries and functions and monitors they might be using.

like image 69
mpm Avatar answered Oct 21 '22 11:10

mpm


According this page:

References are erlang objects with exactly two properties:

They can be created by a program (using make_ref/0), and,
They can be compared for equality.

You should use it ever you need to bind an unique identifier to some "object". Any time you could generate new one using erlang:make_ref/0. Documentation says:

make_ref() -> reference()

Returns an almost unique reference.

The returned reference will re-occur after approximately 2^82 calls; therefore it is unique enough for practical purposes.

When you call erlang:monitor/2 function, it returns you reference to give you availability to cancel monitor (erlang:demonitor/1 function). This reference only identifies certain call of erlang:monitor/1. If you need operate with process (kill it, for example), you still have to use process pid.

Likewise I see monitor/1 receiving a message with a ref and pid number.

Yep, monitor sends messages like {'DOWN', Ref, process, Pid, Reason}. What to use (pid or ref) is only depends on your application logic, but (IMO) in most usual cases, there is no matter what to use.

like image 43
Viacheslav Kovalev Avatar answered Oct 21 '22 12:10

Viacheslav Kovalev