所謂分布式的Erlang應(yīng)用是運行在一系列Erlang節(jié)點組成的網(wǎng)絡(luò)之上。這樣的系統(tǒng)的性質(zhì)與單一節(jié)點上的Erlang系統(tǒng)并沒有什么不同。分布式這是個“大詞”,Erlang從語言原生角度支持分布式編程,相比于java簡單不少。
一、分布式機制
下列的BIFs是用于分布式編程:
spawn(Node, Mod, Func, Args)啟動遠程節(jié)點的一個進程
spawn_link(Node, Mod, Func, Args)啟動遠程節(jié)點的一個進程并創(chuàng)建連接到該進程
monitor_node(Node, Flag)如果Flag是true,這個函數(shù)將使調(diào)用(該函數(shù))的進程可以監(jiān)控節(jié)點Node。如果節(jié)點已經(jīng)舍棄或者并不存在,調(diào)用的進程將收到一個{nodedown,Node}的消息。如果Flag是false,監(jiān)控將被關(guān)閉
node()返回我們自己的進程name
nodes()返回其他已知的節(jié)點name列表
node(Item)返回原來Item的節(jié)點名稱,Item可以是Pid,引用(reference)或者端口(port)
disconnect_node(Nodename)從節(jié)點Nodename斷開。
節(jié)點是分布式Erlang的核心概念。在一個分布式Erlang應(yīng)用中,術(shù)語(term)節(jié)點(node)意味著一個可以加入分布式 transactions的運行系統(tǒng)。通過一個稱為net kernal的特殊進程,一個獨立的Erlang系統(tǒng)可以成為一個分布式Erlang系統(tǒng)的一部分。當(dāng)net kernal進程啟動的時候,我們稱系統(tǒng)是alive的。
與遠程節(jié)點上的進程進行通信,與同一節(jié)點內(nèi)的進程通信只有一點不同:
java 代碼
顯然,需要接收方增加一個參數(shù)Node用于指定接受進程所在的節(jié)點。節(jié)點的name一般是用@隔開的atom類型,比如pong@dennis,表示計算機名為dennis上的pong節(jié)點。通過執(zhí)行:
java 代碼
將在執(zhí)行的計算機中創(chuàng)建一個節(jié)點pong。為了運行下面的例子,你可能需要兩臺計算機,如果只有一臺,只要同時開兩個Erlang系統(tǒng)并以不同的節(jié)點名稱運行也可以。
二、一些例子。
這個例子完全來自上面提到的翻譯的連接,關(guān)于分布式編程的章節(jié)。我增加了截圖和說明。
首先是代碼:
java 代碼
- -module(tut17).
-
- -export([start_ping/1, start_pong/0, ping/2, pong/0]).
-
- ping(0, Pong_Node) ->
- {pong, Pong_Node} ! finished,
- io:format("ping finished~n", []);
-
- ping(N, Pong_Node) ->
- {pong, Pong_Node} ! {ping, self()},
- receive
- pong ->
- io:format("Ping received pong~n", [])
- end,
- ping(N - 1, Pong_Node).
-
- pong() ->
- receive
- finished ->
- io:format("Pong finished~n", []);
- {ping, Ping_PID} ->
- io:format("Pong received ping~n", []),
- Ping_PID ! pong,
- pong()
- end.
-
- start_pong() ->
- register(pong, spawn(tut17, pong, [])).
-
- start_ping(Pong_Node) ->
- spawn(tut17, ping, [3, Pong_Node]).
代碼是創(chuàng)建兩個相互通信的進程,相互發(fā)送消息并通過io顯示在屏幕上,本來是一個單一系統(tǒng)的例子,現(xiàn)在我們讓兩個進程運行在不同的兩個節(jié)點上。注意 start_ping方法,創(chuàng)建的進程調(diào)用ping方法,ping方法有兩個參數(shù),一個是發(fā)送消息的次數(shù),一個就是遠程節(jié)點的name了,也就是我們將要 創(chuàng)建的進程pong的所在節(jié)點。start_pong創(chuàng)建一個調(diào)用函數(shù)pong的進程,并注冊為名字pong(因此在ping方法中可以直接發(fā)送消息給 pong)。
我是在windows機器上測試,首先打開兩個cmd窗口,并cd到Erlang的安裝目錄下的bin目錄,比如C:\Program Files\erl5.5.3\bin,將上面的程序存為tut17.erl,并拷貝到同一個目錄下。我們將創(chuàng)建兩個節(jié)點,一個叫 ping@dennis,一個叫pong@dennis,其中dennis是我的機器名。見下圖:

采用同樣的命令
erl -sname ping創(chuàng)建ping節(jié)點。然后在pong節(jié)點下執(zhí)行start_pong():

OK,這樣就在節(jié)點pong上啟動了pong進程,然后在ping節(jié)點調(diào)用start_ping,傳入?yún)?shù)就是pong@dennis
java 代碼
- tut17:start_ping(pong@dennis).
執(zhí)行結(jié)果如下圖:

同樣在pong節(jié)點上也可以看到:

結(jié)果如我們預(yù)期的那樣,不同節(jié)點上的兩個進程相互通信如此簡單。我們給模塊tut17增加一個方法,用于啟動遠程進程,也就是調(diào)用spawn(Node,Module,Func,Args)方法:
java 代碼
- start(Ping_Node) ->
- register(pong, spawn(tut17, pong, [])),
- spawn(Ping_Node, tut17, ping, [3, node()]).
pong進程啟動Ping_Node節(jié)點上的進程ping。具體結(jié)果不再給出。
posted on 2009-09-11 10:13
暗夜教父 閱讀(426)
評論(0) 編輯 收藏 引用 所屬分類:
erlang