私はO'Reilly Erlang Programmingの書籍から5-2を解決しようとしています。 私の設定はWin10
、werl Eshell V7.3
です。 >C
- - >S
-werlが1つのシェルウィンドウで同じコードを実行し、別のシェルウィンドウでフリーズするのはなぜですか?
frequency:allocate().
c(frequency).
frequency:start().
CTRL-G
:ここに は私の問題を再現する手順です。frequency:deallocate(10).
私はポイント3を省略した場合、すべてはうまく行くが、私は上記の手順に従って、すべてを行う際には、シェルはライン30
または43
で立ち往生。
私は間違って何をしているのか、そしてこれらの2つのケースで全く同じ動作を得る方法を教えてもらえますか?
モジュールのコード(2つの警告がここにありますが、それは私が割り当てが行われていたから、同じ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.