【问题标题】:Programming Erlang(2nd, Armstrong) p.15-18: Why does the shell hang after a second receive?Programming Erlang(2nd, Armstrong) p.15-18: 为什么 shell 在第二次接收后挂起?
【发布时间】:2017-06-14 01:49:24
【问题描述】:

这是我的代码:

-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>

【问题讨论】:

    标签: erlang erlang-shell


    【解决方案1】:

    好的,我在这里找到了答案:

    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不匹配(ok的匹配,但之后没有匹配)。

    解决方案就是为第二次接收使用不同的变量:

    7> receive Y -> Y end.
    

    【讨论】:

    • 虽然在模块函数中您必须使用接收块来访问消息,但在 shell 中有一个预定义的函数可以打印到目前为止收到的所有消息:flush(),它还返回如果消息队列为空,则立即。如果你想阅读一条消息,你必须使用你的方法,然后你可以利用在 shell 中模拟变量赋值,所以有可能忘记一个:f(X) 和 X 将被认为是未绑定的跨度>
    • @Pascal,感谢您的提示。
    猜你喜欢
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    相关资源
    最近更新 更多