Erlang Hot Code加载无法保持状态

时间:2016-02-24 10:30:47

标签: erlang

我是erlang编程的初学者。为了更好地理解热代码加载,我使用了Wikipedia中的示例(我添加了对发送Pid的响应以进行调试):

%% A process whose only job is to keep a counter.
  %% First version
  -module(counter).
  -export([start/0, codeswitch/2]).

  start() -> loop(0).

  loop(Sum) ->
    receive
       {increment, Count} ->
          loop(Sum+Count);
        %% modified code, which will be loaded:
        % reset -> 
        %     loop(0);
       {counter, Pid} ->
          Pid ! {counter, Sum},
          loop(Sum);
        {code_switch, Pid} ->
          Pid ! {switch, Sum},
          ?MODULE:codeswitch(Pid, Sum)
          % Force the use of 'codeswitch/2' from the latest MODULE version
    end.

  codeswitch(FromPid, Sum) -> 
      FromPid ! {switched, Sum},
      loop(Sum).

一切都很好。我可以通过c(counter).在shell中加载模块,通过Pid = spawn(fun counter:start/0).生成一个新进程,并向生成的进程发送消息。当我现在向接收表达式reset -> loop(0)添加新模式并通过c(counter).重新加载代码时,一切都按预期工作,加载新代码,Sum保持其递增值等。

但是,当我发送{code_switch, self()}消息时,Sum会在调用loop(Sum)时重置为0(FromPid ! {switched, Sum}调用FromPid ! {switched, Sum}仍然会返回正确州)。

我错过了什么,为什么我的状态会在第一次调用代码切换函数后消失?

感谢您的帮助!

| 18 | Pid ! {counter, self()}.
{counter,<0.49.0>}
| 19 | flush().
Shell got {counter,6}
ok
| 20 | Pid ! {code_switch, self()}.
{code_switch,<0.49.0>}
| 21 | flush().
Shell got {switch,6}
Shell got {switched,6}
ok
| 22 | Pid ! {counter, self()}.
{counter,<0.49.0>}
| 23 | flush().
Shell got {counter,0}
ok

我将io:format("DebugInfo:~p~n", [Sum])作为loop中的第一个表达式。结果是:

12> Pid ! {code_switch, self()}.
DebugInfo:3
{code_switch,<0.33.0>}
DebugInfo:0
13> flush().
Shell got {switch,3}
Shell got {switched,3}
ok

编辑:我发现当我通过spawn/3(又名spawn(counter, start, []).)生成流程时,这有效。当我通过spawn/1(又名spawn(fun counter:start/0))生成流程时,这不会 工作。这是预期的行为吗?我错过了什么?

spawn/1

Documentation个州:

  

将Fun应用程序启动的新进程的进程标识符返回到空列表[]。否则就像spawn / 3一样。

编辑: .... Aaaand试图在Ubuntu虚拟机上复制它(它没有发生),我现在也无法重现(并将测试我的记忆)现在腐败..)

1 个答案:

答案 0 :(得分:1)

这不是我在测试程序时看到的行为:

25> LPid ! {counter, self()}.
{counter,<0.39.0>}
26> flush().
Shell got {counter,6}
ok
27> c(counter).
{ok,counter}
28> LPid ! {counter, self()}.
{counter,<0.39.0>}
29> flush().                 
Shell got {counter,6}
ok
30> LPid ! {increment, 2}.
{increment,2}
31> LPid ! {counter, self()}.
{counter,<0.39.0>}
32> flush().                 
Shell got {counter,8}
ok
33> LPid ! {code_switch, self()}.
{code_switch,<0.39.0>}
34> flush().                     
Shell got {switch,8}
Shell got {switched,8}
ok
35> LPid ! {counter, self()}.    
{counter,<0.39.0>}
36> flush().                 
Shell got {counter,8}
ok

您是否可以在某些功能中添加io:format("DebugInfo:~p~n", [Sum]).之类的日志来查看正在进行的操作?