Non Blocking Channel Operations in Erlang
In Erlang, we can implement non-blocking channel operations using the receive
statement with a timeout. Here’s how we can translate the Go example:
-module(non_blocking_channel_operations).
-export([main/0]).
main() ->
Messages = spawn(fun() -> message_loop([]) end),
Signals = spawn(fun() -> signal_loop([]) end),
% Here's a non-blocking receive. If a message is
% available, it will be received. If not, the
% after clause will be executed immediately.
receive
{message, Msg} ->
io:format("received message ~p~n", [Msg])
after 0 ->
io:format("no message received~n")
end,
% A non-blocking send works similarly. Here we attempt
% to send a message, but if the receiver is not ready,
% the after clause is executed immediately.
Msg = "hi",
Messages ! {self(), Msg},
receive
ok ->
io:format("sent message ~p~n", [Msg])
after 0 ->
io:format("no message sent~n")
end,
% We can use multiple patterns above the after clause
% to implement a multi-way non-blocking select. Here we
% attempt non-blocking receives on both Messages and Signals.
receive
{message, Msg2} ->
io:format("received message ~p~n", [Msg2]);
{signal, Sig} ->
io:format("received signal ~p~n", [Sig])
after 0 ->
io:format("no activity~n")
end.
message_loop(Messages) ->
receive
{From, Msg} ->
From ! ok,
message_loop([Msg|Messages])
end.
signal_loop(Signals) ->
receive
{From, Sig} ->
From ! ok,
signal_loop([Sig|Signals])
end.
To run the program:
$ erlc non_blocking_channel_operations.erl
$ erl -noshell -s non_blocking_channel_operations main -s init stop
no message received
no message sent
no activity
In this Erlang version, we use processes to simulate channels. The spawn
function creates new processes that run the message_loop
and signal_loop
functions. These functions act as our “channels”, storing messages and signals respectively.
The receive
statement in Erlang is used to receive messages. By adding an after 0 ->
clause, we make the receive non-blocking. If no message is available immediately, the code in the after
clause is executed.
For sending messages, we use the !
operator to send a message to a process. We then immediately try to receive an acknowledgement with a timeout of 0, making it non-blocking.
The multi-way select is implemented using multiple patterns in the receive
statement, followed by an after 0 ->
clause for the default case.
This Erlang code demonstrates the concept of non-blocking operations on channels, albeit using Erlang’s process-based concurrency model rather than Go’s channels.