- Why receive expression is sometimes called selective receive?
- What is the "save queue"?
- How the after section works?
问题:
回答1:
There is a special "save queue" involved in the procedure that when you first encounter the receive expression you may ignore its presence.
Optionally, there may be an after-section in the expression that complicates the procedure a little.
The receive expression is best explained with a flowchart:
receive
pattern1 -> expressions1;
pattern2 -> expressions2;
pattern3 -> expressions3
after
Time -> expressionsTimeout
end
回答2:
Why receive expression is sometimes called selective receive?
-module(my).
%-export([test/0, myand/2]).
-compile(export_all).
-include_lib("eunit/include/eunit.hrl").
start() ->
spawn(my, go, []).
go() ->
receive
{xyz, X} ->
io:format("I received X=~w~n", [X])
end.
In the erlang shell:
1> c(my).
my.erl:3: Warning: export_all flag enabled - all functions will be exported
{ok,my}
2> Pid = my:start().
<0.79.0>
3> Pid ! {hello, world}.
{hello,world}
4> Pid ! {xyz, 10}.
I received X=10
{xyz,10}
Note how there was no output for the first message that was sent, but there was output for the second message that was sent. The receive was selective: it did not receive all messages, it received only messages matching the specified pattern.
What is the "save queue"?
-module(my).
%-export([test/0, myand/2]).
-compile(export_all).
-include_lib("eunit/include/eunit.hrl").
start() ->
spawn(my, go, []).
go() ->
receive
{xyz, X} ->
io:format("I received X=~w~n", [X])
end,
io:format("What happened to the message that didn't match?"),
receive
Any ->
io:format("It was saved rather than discarded.~n"),
io:format("Here it is: ~w~n", [Any])
end.
In the erlang shell:
1> c(my).
my.erl:3: Warning: export_all flag enabled - all functions will be exported
{ok,my}
2> Pid = my:start().
<0.79.0>
3> Pid ! {hello, world}.
{hello,world}
4> Pid ! {xyz, 10}.
I received X=10
What happened to the message that didn't match?{xyz,10}
It was saved rather than discarded.
Here it is: {hello,world}
How the after section works?
-module(my).
%-export([test/0, myand/2]).
-compile(export_all).
-include_lib("eunit/include/eunit.hrl").
start() ->
spawn(my, go, []).
go() ->
receive
{xyz, X} ->
io:format("I received X=~w~n", [X])
after 10000 ->
io:format("I'm not going to wait all day for a match. Bye.")
end.
In the erlang shell:
1> c(my).
my.erl:3: Warning: export_all flag enabled - all functions will be exported
{ok,my}
2> Pid = my:start().
<0.79.0>
3> Pid ! {hello, world}.
{hello,world}
I'm not going to wait all day. Bye.4>
Another example:
-module(my).
%-export([test/0, myand/2]).
-compile(export_all).
-include_lib("eunit/include/eunit.hrl").
sleep(X) ->
receive
after X * 1000 ->
io:format("I just slept for ~w seconds.~n", [X])
end.
In the erlang shell:
1> c(my).
my.erl:3: Warning: export_all flag enabled - all functions will be exported
{ok,my}
2> my:sleep(5).
I just slept for 5 seconds.
ok