Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

自習メモ〜リモートノードの名前付きプロセスにメッセージを送る

補習がてら、Erlangマニュアルの分散プログラミングをやってみました。3.4 Distributed Programmingです。

%
% @see http://www.doyouphp.jp/erlang/getting_started/conc_prog.html
%
-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]).

分散ノード間でメッセージの投げ合うサンプルですが、

    {pong, Pong_Node} ! {ping, self()},

となっているところがポイント。

A difference is how we send messages to a registered process on another node:
{pong, Pong_Node} ! {ping, self()},

We use a tuple {registered_name,node_name} instead of just the registered_name.

ということで、他のノードの名前付きプロセスにメッセージを送る場合、タプルを使うことになるようです。
で、tut17はそれぞれのノードで起動するサンプルなんですが、これを片方のノードで起動するサンプルが次。

%
% @see http://www.doyouphp.jp/erlang/getting_started/conc_prog.html
%
-module(tut18).
-export([start/1, 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(Ping_Node) ->
    register(pong, spawn(tut18, pong, [])),
    spawn(Ping_Node, tut18, ping, [3, node()]).

最後に定義しているstart/1以外はtut17と同じです。start/1では

  • 自ノードでpong/0を実行
  • Ping_Nodeでping/2を実行

となっています。
疎通確認してリモートノードにモジュールをロード後、start/1を実行してみると、結果は「実行したノードのみ」に

(shimooka@win.xxx.yyy)5> tut18:start('shimooka@centos.xxx.yyy').
Pong received ping
<4871.47.0>
(shimooka@win.xxx.yyy)6> Ping received pong
(shimooka@win.xxx.yyy)6> Pong received ping
(shimooka@win.xxx.yyy)6> Ping received pong
(shimooka@win.xxx.yyy)6> Pong received ping
(shimooka@win.xxx.yyy)6> Ping received pong
(shimooka@win.xxx.yyy)6> Ping finished
(shimooka@win.xxx.yyy)6> Pong finished
(shimooka@win.xxx.yyy)6> 

のように出力されます。これは、

This is because the io system finds out where the process is spawned from and sends all output there.

全ての出力が「io:formatを実行しているプロセスを起動したノード」に送られるため、とのことです。なるほど。。。

ノートPC用の冷却ゲル

最近、CF-R4のCPU温度が異様に上がって(80度とか)「もっさり感」が取れなくなる事が多いので、買ってみました。

ELECOM 冷え冷えゲルシート(B5ノートPC対応) SX-B502

ELECOM 冷え冷えゲルシート(B5ノートPC対応) SX-B502

確かに効果はあるみたい。「冷蔵庫・冷凍庫に入れないでください」とあるけど、冷蔵庫で30分ほど冷やすと、かなり効果あり。ただし、3時間も使うと冷却ゲル自体が熱を持ってしまうので、ローテーション用のスペアが欲しいところ。
まあ、そんなにCPU温度が上がるようなことをしなければ良いだけの話かも知れませんが。。。