莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          Erlang入門(三)——分布式編程

          Posted on 2007-06-15 17:33 dennis 閱讀(5509) 評論(1)  編輯  收藏 所屬分類: erlang
              明天要回家一個星期了,好好休息下。今天找到別人翻譯的Erlang編程手冊,值的好好讀一遍。
              所謂分布式的Erlang應用是運行在一系列Erlang節點組成的網絡之上。這樣的系統的性質與單一節點上的Erlang系統并沒有什么不同。分布式這是個“大詞”,Erlang從語言原生角度支持分布式編程,相比于java簡單不少。
          一、分布式機制
          下列的BIFs是用于分布式編程:
          spawn(Node, Mod, Func, Args)
          啟動遠程節點的一個進程

          spawn_link(Node, Mod, Func, Args)
          啟動遠程節點的一個進程并創建連接到該進程

          monitor_node(Node, Flag)
          如果Flag是true,這個函數將使調用(該函數)的進程可以監控節點Node。如果節點已經舍棄或者并不存在,調用的進程將收到一個{nodedown,Node}的消息。如果Flag是false,監控將被關閉

          node()
          返回我們自己的進程name

          nodes()
          返回其他已知的節點name列表

          node(Item)
          返回原來Item的節點名稱,Item可以是Pid,引用(reference)或者端口(port)

          disconnect_node(Nodename)
          從節點Nodename斷開。

              節點是分布式Erlang的核心概念。在一個分布式Erlang應用中,術語(term)節點(node)意味著一個可以加入分布式transactions的運行系統。通過一個稱為net kernal的特殊進程,一個獨立的Erlang系統可以成為一個分布式Erlang系統的一部分。當net kernal進程啟動的時候,我們稱系統是alive的。

              與遠程節點上的進程進行通信,與同一節點內的進程通信只有一點不同:
            
             {Name, Node} ! Mess.
          顯然,需要接收方增加一個參數Node用于指定接受進程所在的節點。節點的name一般是用@隔開的atom類型,比如pong@dennis,表示計算機名為dennis上的pong節點。通過執行:
          erl -sname pong
          將在執行的計算機中創建一個節點pong。為了運行下面的例子,你可能需要兩臺計算機,如果只有一臺,只要同時開兩個Erlang系統并以不同的節點名稱運行也可以。

          二、一些例子。
              這個例子完全來自上面提到的翻譯的連接,關于分布式編程的章節。我增加了截圖和說明。
          首先是代碼:
          -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]).

              代碼是創建兩個相互通信的進程,相互發送消息并通過io顯示在屏幕上,本來是一個單一系統的例子,現在我們讓兩個進程運行在不同的兩個節點上。注意start_ping方法,創建的進程調用ping方法,ping方法有兩個參數,一個是發送消息的次數,一個就是遠程節點的name了,也就是我們將要創建的進程pong的所在節點。start_pong創建一個調用函數pong的進程,并注冊為名字pong(因此在ping方法中可以直接發送消息給pong)。
              我是在windows機器上測試,首先打開兩個cmd窗口,并cd到Erlang的安裝目錄下的bin目錄,比如C:\Program Files\erl5.5.3\bin,將上面的程序存為tut17.erl,并拷貝到同一個目錄下。我們將創建兩個節點,一個叫ping@dennis,一個叫pong@dennis,其中dennis是我的機器名。見下圖:

          采用同樣的命令
          erl -sname ping
          創建ping節點。然后在pong節點下執行start_pong():


          OK,這樣就在節點pong上啟動了pong進程,然后在ping節點調用start_ping,傳入參數就是pong@dennis
          tut17:start_ping(pong@dennis).
          執行結果如下圖:

          同樣在pong節點上也可以看到:


              結果如我們預期的那樣,不同節點上的兩個進程相互通信如此簡單。我們給模塊tut17增加一個方法,用于啟動遠程進程,也就是調用spawn(Node,Module,Func,Args)方法:
          start(Ping_Node) ->
              register(pong
          , spawn(tut17, pong, [])),
              spawn(Ping_Node
          , tut17, ping, [3, node()]).
          pong進程啟動Ping_Node節點上的進程ping。具體結果不再給出。



              


          評論

          # re: Erlang入門(三)——分布式編程  回復  更多評論   

          2013-04-21 13:43 by 楊雪松
          ping節點給pong節點發消息的時候用的是{Pid, Node}來確定目標,而pong回復消息給ping時直接用了Pid沒有指名Node,這里為何可以省去Node信息呢?
          主站蜘蛛池模板: 绥中县| 嘉定区| 根河市| 鸡西市| 昭平县| 大兴区| 文成县| 东山县| 桑植县| 雷州市| 綦江县| 商水县| 胶州市| 辉南县| 依兰县| 鸡西市| 屯门区| 南溪县| 梅河口市| 大同县| 霍城县| 乐清市| 谢通门县| 偃师市| 镇康县| 巴彦淖尔市| 洞头县| 翁源县| 四子王旗| 礼泉县| 乌拉特前旗| 湾仔区| 龙江县| 浦城县| 贵港市| 宾阳县| 桐梓县| 延边| 景泰县| 洞头县| 吕梁市|