2016-08-15 9 views
3

私はO'Reilly Erlang Programmingの書籍から5-2を解決しようとしています。 私の設定はWin10werl Eshell V7.3です。 >C - - >S -werlが1つのシェルウィンドウで同じコードを実行し、別のシェルウィンドウでフリーズするのはなぜですか?

  • frequency:allocate().

    シェル新しいアーランに切り替える

    1. c(frequency).

    2. frequency:start().

    3. CTRL-G:ここに は私の問題を再現する手順です。

    4. 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. 
    
  • 答えて

    1

    私はそうではありませんこの問題の完全な説明ですが、io:formatの使用法にリンクしています。曖昧な(私にとってはあいまいです:o)グループリーダーの概念があります。 。

    一般に、サーバープロセスで実行されるサーバーループ内にメッセージを表示することはお勧めできませんが、呼び出しプロセスで実行されるインターフェイス関数で実行する方が効果的です。

    コードを少し変更して、無駄なプリントを削除し、pidのテストを修正し、複数のシェルでうまく動作します。

    -module(freq). 
    -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(freq, 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(), 
        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, Pid, {deallocate, Freq}} -> 
         {NewFrequencies,Reply} = deallocate(Frequencies, Freq, Pid), 
         reply(Pid, Reply), 
         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), 
        case Response of 
        {value, {Freq, Pid}} -> 
         NewAllocated = lists:keydelete(Freq, 1, Allocated), 
         {{[Freq|Free], NewAllocated},removed}; 
        {value, {Freq, _OtherPid}} -> 
         {{Free, Allocated},not_owner}; 
        _ -> 
         {{Free, Allocated},not_found} 
        end. 
    
    関連する問題