Я пытаюсь решить упражнение 5-2 из книги O'Reilly Erlang Programming. Моя установка Win10
, werl Eshell V7.3
. Вот шаги, чтобы воспроизвести мою проблему:
c(frequency).
frequency:start().
CTRL-G
->S
->C
-- для переключения на новую оболочку Erlangfrequency:allocate().
frequency:deallocate(10).
Если я опускаю пункт 3, то все идет нормально, но когда я делаю все по вышеуказанной процедуре, то оболочка застревает в строке 30
или 43
.
Может кто-нибудь объяснить мне, что я делаю неправильно и как добиться одинакового поведения для этих двух случаев: с одной и с двумя оболочками?
Код модуля (здесь есть два предупреждения, но он все равно компилируется, я пытался разрешить освобождение только при вызове из того же Pid, из которого выполнялось выделение):
-module(frequency).
-export([start/0, stop/0, allocate/0, deallocate/1]).
-export([init/0]).
%% These are the start functions used to crate and
%% initialize the server.
start() ->
register(frequency, spawn(frequency, init, [])).
init() ->
Frequencies = {get_frequencies(), []},
loop(Frequencies).
% Hard Coded
get_frequencies() -> [10, 11, 12, 13, 14, 15].
%% The client Functions
stop() -> call(stop).
allocate() -> call(allocate).
deallocate(Freq)-> io:format("Calling deallocate~n",[]), call({deallocate, Freq}).
%% We hide all message passing and the message
%% protocol in a functional interface.
call(Message) ->
Self = self(),
io:format("Self: ~w~n", [Self]),
frequency ! {request, Self, Message},
receive
{reply, Reply} -> Reply
end.
%% The Main Loop
loop(Frequencies) ->
receive
{request, Pid, allocate} ->
{NewFrequencies, Reply} = allocate(Frequencies, Pid),
reply(Pid, Reply),
loop(NewFrequencies);
{request, Pid2, {deallocate, Freq}} ->
io:format("Dealocate ~w from pid ~w~n", [Freq, Pid2]),
NewFrequencies = deallocate(Frequencies, Freq), %, Pid2),
reply(Pid2, ok),
loop(NewFrequencies);
{request, Pid, stop} ->
reply(Pid, ok)
end.
reply(Pid, Reply) ->
Pid ! {reply, Reply}.
%% The Internal Help Functions used to allocate and
%% deallocate frequencies.
allocate({[], Allocated}, _Pid) ->
{{[], Allocated}, {error, no_frequency}};
allocate({[Freq|Free], Allocated}, Pid) ->
{{Free, [{Freq, Pid}| Allocated]}, {ok, Freq}}.
deallocate({Free, Allocated}, Freq) -> %, Pid) ->
Response = lists:keysearch(Freq, 1, Allocated),
io:format("Response: ~w~n", [Response]),
case Response of
{value, {Freq, OPid}} ->
case OPid of
Pid ->
NewAllocated = lists:keydelete(Freq, 1, Allocated),
io:format("Removed freq~n",[]),
{[Freq|Free], NewAllocated};
_OtherPid ->
io:format("Not allowed to remove freq~n",[]),
{Free, Allocated}
end;
_ -> io:format("Not removed freq~n",[]), {Free, Allocated}
end.