我是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
的
将Fun应用程序启动的新进程的进程标识符返回到空列表[]。否则就像spawn / 3一样。
编辑: .... Aaaand试图在Ubuntu虚拟机上复制它(它没有发生),我现在也无法重现(并将测试我的记忆)现在腐败..)
答案 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]).
之类的日志来查看正在进行的操作?