Most programming languages implement concurrency poorly, Erlang has taken a different approach to concurrency than today’s popular programming language, as we’ve seen, it is easy to create parallel processes of execution in Erlang. Lets look more closely at how to create and communicate with these processes in Erlang by creating a small (contrived and basic) program which simulates a buyer buying stocks from a seller.
We need three Erlang primitives to work with processes: spawn, ! and receive. The built-in spawn function creates a new process executing a function and returns the new process’ process id. The ! operator sends a message to a process and processes use the receive...end function to match messages in the mailbox to patterns and execute the appropriate functions.
To send a message “BUY MSFT” to the Seller process, we use:
Seller ! {{buy, msft} , Buyer}
we include the variable Buyer which contains the process id of the buyer, this lets the seller know which process to send the acknowledgment to. Now we need to create the Seller process, we do this by calling the spawn/3 function– the first argument to spawn is the module name, followed by the function name and ending with a list of arguments:
Seller_pid = spawn(exchange, seller, [])
Both the Buyer and Seller processes can handle the message using pattern matching in the receive..end clause, Here the Seller process receives the {buy, Symbol} message, processes it, and then acknowledges the transaction by sending an “ok” to the buyer:
seller() ->
receive
{finished, _} ->
io:format("Received finished. no one is buying~n", []);
{{buy, Symbol}, Buyer_pid} ->
io:format("sold ~s to buyer~n", [Symbol]),
Buyer_pid ! ok,
seller();
end.
Now, lets put these pieces together in a program in which the Buyer process buys Stocks from the Seller and in return, the Seller process acknowledges the sale; the program terminates when the Buyer has run out of Stocks to buy.
-module(exchange).
-export([start/0, buyer/2, seller/0]).
buyer([], Seller_pid) ->
Seller_pid ! {finished, self()},
%% note there's a ";" instead of a "." at the end of the next clause
io:format("buyer finished~n", []);
buyer(List, Seller_pid) ->
[Head|Tail] = List,
Seller_pid ! {Head, self()},
receive
ok ->
io:format("buyer received seller confirmation~n", [])
end,
buyer(Tail, Seller_pid).
seller() ->
receive
{finished, _} ->
io:format("Received finished. no one is buying~n", []);
{{buy, Symbol}, Buyer_pid} ->
io:format("sold ~s to buyer~n", [Symbol]),
Buyer_pid ! ok,
seller()
%% note there's, no ";" or "," before the end
end.
start() ->
Things_to_buy = [{buy, sina}, {buy, msft}, {buy, intc}],
Seller_pid = spawn(exchange, seller, []),
spawn(exchange, buyer, [Things_to_buy, Seller_pid]).
The program illustrates the most basic ways to use Erlang processes, I’ve completely skipped over guards, error handling, timeouts and registered processes, but several detailed documents on these topics and Erlang design principles are available on there ftp site.
Related posts:





Leave a Reply