Выполнение процессов связи

Я только что начал читать книгу Programming Erlang. Существует очень единственный пример, который работает только с файлом.

Если я выполняю:

> c(afile_server).
> c(afile_client).
> Server = afile_server:start(".").
> client:get_file(Server, "file1").
> client:get_file(Server, "file2").
> client:get_file(Server, "file3").

Все работает только файл. Отображается содержимое трех файлов.

Но если я сделаю:

> c(afile_server).
> Server = afile_server:start(".").
> Server ! { self(), { get_file, "file1" } }.
> receive 
   { Server, Content }
      Content
  end.

Работает просто файл. Но если я изменю файл, который я пытаюсь прочитать (после первого вызова), например.

> Server ! { self(), { get_file, "file2" } }.
> receive 
   { Server, Content }
      Content
  end.

Блоки приема и ничего не возвращается. Не могли бы вы как-то помочь? Думаю, это очень глупая ошибка! С уважением.

Файлы:

Сервер:

-module(afile_server).
-export([start/1, loop/1]).

start(Dir) -> spawn(afile_server, loop, [Dir]).

loop(Dir) ->
    receive
    {Client, list_dir} ->
        Client ! {self(), file:list_dir(Dir)};
    {Client, {get_file, File}} ->
        Full = filename:join(Dir, File),
        Client ! {self(), file:read_file(Full)}
    end,
    loop(Dir).

Клиент

%% ---
%%  Excerpted from "Programming Erlang, Second Edition",
%%  published by The Pragmatic Bookshelf.
%%  Copyrights apply to this code. It may not be used to create training material, 
%%  courses, books, articles, and the like. Contact us if you are in doubt.
%%  We make no guarantees that this code is fit for any purpose. 
%%  Visit http://www.pragmaticprogrammer.com/titles/jaerlang2 for more book information.
%%---
-module(afile_client).
-export([ls/1, get_file/2]).

ls(Server) ->
    Server ! {self(), list_dir},
    receive 
    {Server, FileList} ->
        FileList
    end.

get_file(Server, File) ->
    Server ! {self(), {get_file, File}},
    receive 
    {Server, Content} ->
        Content
    end.

person Nadilson Ferreira    schedule 29.09.2016    source источник


Ответы (1)


Это потому, что вы запускаете это в оболочке и повторно используете имя Content в шаблоне receive, а 2 файла предположительно имеют разное содержимое в вашей файловой системе, поэтому receive блокируется до тех пор, пока процесс не получит сообщение с тем же содержимым. Чтобы исправить это, вы можете либо использовать другое имя для Content каждый раз, либо явно «забыть» переменную, используя f(Content).

1> c(afile_server).
{ok,afile_server}
2> Server = afile_server:start(".").
<0.64.0>
3> Server ! { self(), { get_file, "file1" } }.
{<0.57.0>,{get_file,"file1"}}
4> receive {Server, Content} -> Content end.
{ok,<<"file1\n">>}
5> Server ! { self(), { get_file, "file2" } }.
{<0.57.0>,{get_file,"file2"}}
6> receive {Server, Content} -> Content after 1000 -> timeout end.
timeout
7> receive {Server, Content2} -> Content2 end.
{ok,<<"file2\n">>}
8> Server ! { self(), { get_file, "file3" } }.
{<0.57.0>,{get_file,"file3"}}
9> receive {Server, Content} -> Content after 1000 -> timeout end.
timeout
10> f(Content).
ok
11> receive {Server, Content} -> Content after 1000 -> timeout end.
{ok,<<"file3\n">>}
person Dogbert    schedule 29.09.2016