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.