【问题标题】:Why dont I get any terminal output after hot code loading in Erlang?为什么我在 Erlang 中热加载代码后没有任何终端输出?
【发布时间】:2018-11-19 23:09:07
【问题描述】:

在尝试了解如何使用服务器和热代码加载时,我偶然发现了一个问题,我将其简化为以下代码:

server.erl

-module(server).
-export([start/0, connect/1]).

start() ->
    {ok, Listen} = gen_tcp:listen(8080, [binary, {packet, raw}, {active, true}]),
    spawn(?MODULE, connect, [Listen]).

connect(Listen) ->
    {ok, Socket} = gen_tcp:accept(Listen),
    spawn(?MODULE, connect, [Listen]),
    loop(Socket).

loop(Socket) ->
    receive
        {tcp, Socket, Data} ->
            io:format("1st version received ~p~n", [Data]),
            loop(Socket);
        {tcp_closed, Socket} ->
            io:format("socket closed~n")
    end.

client.erl

-module(client).
-export([request/0]).

request() ->
    {ok, Socket} = gen_tcp:connect("localhost", 8080, [{packet, raw}, binary]),
    gen_tcp:send(Socket, <<"Hello">>).

启动服务器并发送请求会创建预期的输出。

1> server:start().
<0.62.0>
2> client:request().
ok
1st version received <<"Hello">>

将格式语句更改为“2nd version”后,编译加载代码并执行两个请求(因为在更改之前产生了当前等待连接的connect/1进程),结果仍然符合预期。

3> c(server).       
{ok,server}
4> client:request().
ok
1st version received <<"Hello">>
5> client:request().
ok
2nd version received <<"Hello">>

但是,在连续两次编译加载代码后,终端中不再打印输出,尽管服务器显然仍在运行,因为 gen_tcp:connect 返回一个套接字。

6> c(server).
{ok,server}
7> c(server).
{ok,server}
8> client:request().
ok

我怀疑这种行为与 erlang 杀死所有代码早于两个版本的进程有关,但我无法真正理解这里发生了什么。 由于这是教育性的,我更感兴趣的是知道为什么这个确切的代码不起作用,而不是问题的实际解决方案。

谢谢

【问题讨论】:

    标签: erlang


    【解决方案1】:

    我很确定这是两个版本的限制。

    如果您想确认这一点,请将调用从 spawn(...) 替换为 spawn_link(...) -- 如果进程终止,您的 shell 也会崩溃并且您会知道它们已被终止。

    另一种测试方法是是否可以替换以下内容:

    6> c(server).
    {ok,server}
    7> c(server).
    {ok,server}
    8> client:request().
    ok
    

    作者:

    6> c(server).
    {ok,server}
    7> client:request().
    ok
    8> c(server).
    {ok,server}
    9> client:request().
    ok
    

    如果这工作正常,区别在于中间的消息允许代码更新到完全限定函数调用 (Module:Fun(Args)) 的新代码版本,从而防止崩溃。

    【讨论】:

    • 使用 spawn_link 显示进程在两次更新后被杀死,并且当在两者之间发送消息时它仍然有效。我对连接哪些进程感到困惑,但现在它开始变得有意义了。
    猜你喜欢
    • 2018-08-09
    • 1970-01-01
    • 2021-02-07
    • 2021-02-24
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多