When I saw the registration process in Erlang before, I didn’t understand the registration, mainly because I didn’t understand the scope of the registered atom. I suddenly figured it out:
Register the atom associated with the process has a global scope
That is to say, the atoms associated with the registration process can be used globally
The concurrency mechanism in Erlang is implemented through message mailbox. The only way to communicate between processes is the message mailbox. Inter-process communication requires knowing the process number of the process. When spawning a new process, the process number of the new process will be returned for use.
The simplest inter-process communication program is as follows
-module(test).
start() ->
spawn(?MODULE, loop, []).
loop() ->
io:format("Waiting for new message.~n"),
receive
M -> io:format("New message: ~p~n", [M])
end,
loop().
Use c(test) to compile this module in Erlang Shell, and then it can be used simply.
In the following code, the comments before the statement represent explanation, the comments after the statement represent the output value, and % => The value after the statement represents the return value of the statement
% Compile this module
c(test).
% Turn on infinite loop
Pid = test:start().
% Waiting for new message.
% => <0.35.0> �
% Send a message to the process
Pid ! 'message'.
% New message: message �
% Waiting for new message.
% => message
In order for users not to Pid ! 'message' every time, you can add a call method to wrap it.
call(Pid, M) ->
Pid ! M.
This way you can use test:call(Pid, 'message') to send messages.
However, there is an obvious disadvantage to writing this way. The Pid parameter is required when calling the call, but it cannot be removed because the process number is required to communicate, so the user needs to maintain a process number when using it.
Erlang provides a mechanism to register a process to associate atoms into the process, which can solve this problem
Use register(atom, Pid) to associate atom to a process with process number Pid, and this atom is
Modify the start function above to
start() ->
register(testp, spawn(?MODULE, loop, [])).
In this way, the new process will be associated with the atom testp, and the atom can be used as a Pid as a "message sending operator"!
testp ! 'message'
Therefore, you can modify the call function above, remove the Pid parameter, and use the associated atoms, which are not only valid in the module, but are all valid in the global scope.
call(M) ->
testp ! M.
Therefore, the modified program using the registration process is as follows
-module(test).
start() ->
register(testp, spawn(?MODULE, loop, [])).
loop() ->
io:format("Waiting for new message.~n"),
receive
M -> io:format("New message: ~p~n", [M])
end,
loop().
call(M) ->
testp ! M.
Register related BIF
% Register atom to Pid
register(atom, Pid).
% Cancel atom registration
unregister(atom).
% Returns the process number associated with atom, if not associated, returns undefined
whereis(atom).
% Returns all registered process names in the system
registered().