Programming Erlang(2nd, Armstrong) p.15-18:为什么 shell 在第二个接收后挂起?
Programming Erlang(2nd, Armstrong) p.15-18: Why does the shell hang after a second receive?
这是我的代码:
-module(afile_server).
-export([start/1, loop/1]).
start(Dir) ->
spawn(afile_server, loop, [Dir]).
loop(Dir) ->
receive
{Client, list_files} ->
Client ! {self(), file:list_dir(Dir)};
{Client, {get_file, File}} ->
Full = filename:join(Dir, File),
Client ! {self(), file:read_file(Full)}
end,
loop(Dir).
以下是 shell 命令:
$ erl
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V6.4 (abort with ^G)
2> c(afile_server).
{ok,afile_server}
3> Server = afile_server:start(".").
<0.43.0>
4> Server ! {self(), list_files}.
{<0.32.0>,list_files}
5> receive X -> X end.
{<0.43.0>,
{ok,["afile_client.erl","afile_server.beam",
"afile_server.erl","hello.beam","hello.erl","old"]}}
6> Server ! {self(), {get_file, "hello.erl"}}.
{<0.32.0>,{get_file,"hello.erl"}}
7> receive X -> X end.
<hangs>
好的,我在这里找到了答案:
http://erlang.org/pipermail/erlang-questions/2007-April/026121.html
谢谢安德斯·尼格伦!
对于第一次接收,X 开始未绑定,它将匹配任何内容。当第一个接收检查来自文件服务器的消息时,X 被绑定到消息,即值:
{ok,["afile_client.erl","afile_server.beam",
"afile_server.erl","hello.beam","hello.erl","old"]}}
在第二个接收中,X 已经绑定,因此接收正在寻找匹配项:
{ok,["afile_client.erl","afile_server.beam",
"afile_server.erl","hello.beam","hello.erl","old"]}}
第二次接收挂起,因为文件服务器发送的消息是:
{ok,<<"-module(hello).\n-export([start/0]).\n\nstart() ->
io:format(\"hello world~n\").\n">>}}
与 X 不匹配(好的匹配,但之后没有匹配)。
解决方案是为第二次接收使用不同的变量:
7> receive Y -> Y end.
这是我的代码:
-module(afile_server).
-export([start/1, loop/1]).
start(Dir) ->
spawn(afile_server, loop, [Dir]).
loop(Dir) ->
receive
{Client, list_files} ->
Client ! {self(), file:list_dir(Dir)};
{Client, {get_file, File}} ->
Full = filename:join(Dir, File),
Client ! {self(), file:read_file(Full)}
end,
loop(Dir).
以下是 shell 命令:
$ erl
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V6.4 (abort with ^G)
2> c(afile_server).
{ok,afile_server}
3> Server = afile_server:start(".").
<0.43.0>
4> Server ! {self(), list_files}.
{<0.32.0>,list_files}
5> receive X -> X end.
{<0.43.0>,
{ok,["afile_client.erl","afile_server.beam",
"afile_server.erl","hello.beam","hello.erl","old"]}}
6> Server ! {self(), {get_file, "hello.erl"}}.
{<0.32.0>,{get_file,"hello.erl"}}
7> receive X -> X end.
<hangs>
好的,我在这里找到了答案:
http://erlang.org/pipermail/erlang-questions/2007-April/026121.html
谢谢安德斯·尼格伦!
对于第一次接收,X 开始未绑定,它将匹配任何内容。当第一个接收检查来自文件服务器的消息时,X 被绑定到消息,即值:
{ok,["afile_client.erl","afile_server.beam",
"afile_server.erl","hello.beam","hello.erl","old"]}}
在第二个接收中,X 已经绑定,因此接收正在寻找匹配项:
{ok,["afile_client.erl","afile_server.beam",
"afile_server.erl","hello.beam","hello.erl","old"]}}
第二次接收挂起,因为文件服务器发送的消息是:
{ok,<<"-module(hello).\n-export([start/0]).\n\nstart() ->
io:format(\"hello world~n\").\n">>}}
与 X 不匹配(好的匹配,但之后没有匹配)。
解决方案是为第二次接收使用不同的变量:
7> receive Y -> Y end.