2014-12-21 62 views
2

我想要遵循編程Erlang,喬阿姆斯特朗併發世界軟件中給出的第一個例子。下面是代碼:文件服務器erlang響應

-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). 

然後我在shell中運行以下命令:

c(afile_server). 
FileServer = spawn(afile_server, start, "."). 
FileServer ! {self(), list_dir}. 
receive X -> X end. 

在這本書中返回文件的列表作爲我的殼但是預計它看起來好像程序有凍結。程序仍在運行,沒有任何東西會返回。我對erlang並不熟悉,但是我可以理解這是如何工作的。

我在Windows 7 64位運行此。該目錄不是空的,因爲它包含一堆其他的erlang文件。

回答

7

那麼... start/1函數在這裏做什麼?它產生了一個從loop/1開始的過程,你不只是在你的shell中運行它,但它也會產生它!所以你有一連串兩個衍生進程和FileServer死亡imiedietly死,因爲它唯一的工作是派生出實際的文件服務器,你不知道pid。

只是改變行:

FileServer = spawn(afile_server, start, ".").

到:

FileServer = afile_server:start(".").

+0

我在這本書再看一看。看來我沒有正確閱讀該行。 – Bula

+0

但是,爲什麼不工作?我的意思是。 PID沒有指向這個過程嗎? – Bula

+0

@Bula PID指向處理哪個派生文件服務器。這是暫時的,並在產生你的服務器進程後死亡,但仍然存在,但你有指向臨時進程的PID。你可以把它當作父母,文件服務器是它的孩子。你想要這個孩子的PID而不是它的父母。你的shell應該是它的父類,但是在你的代碼中,它變成了它的祖父母,它們之間有不需要的過程。產卵意味着:創建一個獨立的進程,開始執行你傳遞的函數並返回它的PID。誰會產卵afile_server:然後呢? Proc你在shell中產生,而不是shell。 –

5

下圖說明盧卡斯解釋。

enter image description here enter image description here

+0

你用什麼工具繪製圖表? – J4cK

+1

這是Chrome的插件:gliffy。我不記得我用來添加陰影的繪圖工具。 – Pascal

+0

謝謝@Pascal :) – J4cK