为什么第二次调用 receive 没有在 Erlang shell 中检索消息?
Why second call to receive doesn't retrieve a message in Erlang shell?
我正在玩弄 Erlang 中的进程并尝试创建一个简单的计数器进程。
它接收发送者的 PID,增加内部计数器并将新的计数器值发送给发送者。
我从 erl shell (Erlang/OTP 20, Eshell V9.2) 启动我的代码。
而且我能够成功收到来自计数器进程的第一个回复,但不是第二个。
%% Process function that serves as a counter
CounterFun = fun() ->
(fun Receiver(Current) ->
io:format(" -- Entering receiver, current ~p~n", [Current]),
receive
Sender ->
New = Current + 1,
io:format(" -- Sending ~p to ~p~n", [New, Sender]),
Sender ! New,
Receiver(New)
end
end)(0)
end.
CounterPid = spawn(CounterFun).
CounterPid ! self().
receive V -> V after 3000 -> timeout end. % Will provide 1
CounterPid ! self().
receive V -> V after 3000 -> timeout end. % Will result in timeout
这是它在我的控制台中的样子。
第一次receive将变量V
绑定到1
,所以第二次receive变成:
receive
1 -> ...
end
而且,由于消息 1
从未到达,第二次接收超时。超时后,你可以在shell中调用flush()
,你会看到邮箱里有一条消息2
。您还可以随时调用 b()
以显示当前变量及其值(称为绑定)——在执行第一个接收后尝试。
在您的函数中,您还在接收中的接收中进行递归接收,以便第一个接收永远不会结束。为了证明这一点,你可以在:
之后加上打印语句
Receiver(New)
赞:
io:format("receive ending with Current= ~w~n", [Current])
而且您将永远看不到任何输出。您应该将接收更改为如下内容:
New = Currrent + 1
receive
Sender ->
io:format(" -- Sending ~p to ~p~n", [New, Sender]),
Sender ! New,
io:format("receive ending with Current= ~w~n", [Current])
end,
counter(New).
我正在玩弄 Erlang 中的进程并尝试创建一个简单的计数器进程。 它接收发送者的 PID,增加内部计数器并将新的计数器值发送给发送者。 我从 erl shell (Erlang/OTP 20, Eshell V9.2) 启动我的代码。 而且我能够成功收到来自计数器进程的第一个回复,但不是第二个。
%% Process function that serves as a counter
CounterFun = fun() ->
(fun Receiver(Current) ->
io:format(" -- Entering receiver, current ~p~n", [Current]),
receive
Sender ->
New = Current + 1,
io:format(" -- Sending ~p to ~p~n", [New, Sender]),
Sender ! New,
Receiver(New)
end
end)(0)
end.
CounterPid = spawn(CounterFun).
CounterPid ! self().
receive V -> V after 3000 -> timeout end. % Will provide 1
CounterPid ! self().
receive V -> V after 3000 -> timeout end. % Will result in timeout
这是它在我的控制台中的样子。
第一次receive将变量V
绑定到1
,所以第二次receive变成:
receive
1 -> ...
end
而且,由于消息 1
从未到达,第二次接收超时。超时后,你可以在shell中调用flush()
,你会看到邮箱里有一条消息2
。您还可以随时调用 b()
以显示当前变量及其值(称为绑定)——在执行第一个接收后尝试。
在您的函数中,您还在接收中的接收中进行递归接收,以便第一个接收永远不会结束。为了证明这一点,你可以在:
之后加上打印语句Receiver(New)
赞:
io:format("receive ending with Current= ~w~n", [Current])
而且您将永远看不到任何输出。您应该将接收更改为如下内容:
New = Currrent + 1
receive
Sender ->
io:format(" -- Sending ~p to ~p~n", [New, Sender]),
Sender ! New,
io:format("receive ending with Current= ~w~n", [Current])
end,
counter(New).