2012-12-01 4 views
1

Erlang을 배우려고하는데 다른 노드로 메시지를 보낼 때 문제가 있습니다. 이 프로그램은 이처럼 작동해야하는 아주 간단한 탁구대 일뿐입니다. 노드 m1 @ ASUS-N55SF에서 프로그램을 시작합니다. 프로세스를 생성하고 노드 m2에서 프로세스를 성공적으로 생성합니다. 그래서 {PidPing, PidPong} 튜플을 포함하는 Pid를 얻습니다. PidPing 및 PidPong은 < 0.X.0> 및 < Y.Z.0>과 같은 프로세스 ID입니다. start_pinging (PIDS) 기능과 I 오류 얻을 : 그 후
나는 PS5 전화한 노드에서 다른 노드로 Erlang 메시지를 보내면 badarg을 반환합니다.

Pinging started 
Ping received 0 on <0.53.0> 
{ping,{<0.53.0>,<6807.43.0>},0} 
Nodes: '[email protected]' '[email protected]' 
([email protected])8> 
=ERROR REPORT==== 1-Dec-2012::15:27:18 === 
Error in process <0.53.0> on node '[email protected]' with exit 
value: {badarg,[{ps5,loop_ping,0,[{file,"ps5.erl"},{line,33}]}]} 

그래서 초기 메시지가 PidPing에 수신 및 successfuly 일치 loop_ping에 도달하지만 다른 메시지를 보낼 수 없습니다를 노드가 서로에게 보이더라도. 이 초기 메시지가 동일한 노드에 전송되기 때문에 이 suceeds :

PidPing ! {pong, {PidPing, PidPong}, 0}. 

내가 다른 노드로 메시지를 보낼 알 수있는 바와 같이 나는 같은 메시지를 보내야합니다 :

{PidPong, ?NODE_TP} ! {pong, {PidPing, PidPong}, Number + 1}, 

하지만 badarg를 반환합니다. 노드는 연결되어 동일한 쿠키로 시작되고 동일한 시스템에서 실행되며 서로 핑하고 볼 수 있습니다. 동일한 폴더에서 시작되므로 동일한 ps5.erl 파일을 볼 수 있습니다. 나는 다른 폴더에서 시도했지만 역시 작동하지 않습니다. seme 노드에서 코드가 실행되면 다른 노드에서 스폰를 제거하고 같은 노드에서 프로세스를 만드는 것만으로 작동합니다.

-module(ps5). 
-define(NODE_AS, '[email protected]'). 
-define(NODE_TP, '[email protected]'). 
%-define(NODE_TP, '[email protected]'). 

-compile(export_all). 
start() -> 
    PidPing = ps5:start_ping(), 
    PidPong = ps5:start_pong(), 
    Pids = {PidPing, PidPong}. 

start_ping() -> 
    Pid = spawn(?NODE_AS, ps5, loop_ping, []). 

start_pong() -> 
    Pid = spawn(?NODE_TP, ps5, loop_pong, []). 

start_pinging({PidPing, PidPong}) -> 
    io:format("Pinging started ~n", []), 
    PidPing ! {ping, {PidPing, PidPong}, 0}. 

stop({PidPing, PidPong}) -> 
    exit(PidPing, normal), 
    exit(PidPong, normal). 

loop_ping() -> 
    receive 
    {ping, {PidPing, PidPong}, Number} when Number < 10 -> 
     io:format("Ping received ~p on ~p~n", [Number, PidPing]), 
     io:format("Nodes: ~p ~p ~n", [?NODE_AS, ?NODE_TP]), 
     {PidPong, ?NODE_TP} ! {pong, {PidPing, PidPong}, Number + 1}, 
     io:format("Ping sent ping ~p to ~p~n", [Number, PidPong]), 
     ps5:loop_ping(); 
    {ping, {PidPing, PidPong}, Number} when Number >= 10-> 
     io:format("Ping received ~p on ~p~n and closing.~n", [Number, PidPing]); 
    Oops -> 
     io:format("Oops received: ~p~n", [Oops]), 
     ps5:loop_ping() 
    end. 

loop_pong() -> 
    receive 
    {pong, {PidPing, PidPong}, Number} when Number < 10 -> 
    io:format("Pong received ~p on ~p~n", [Number, PidPong]), 
    io:format("Nodes: ~p ~p ~n", [?NODE_AS, ?NODE_TP]), 
    {PidPing, ?NODE_AS} ! {ping, {PidPing, PidPong}, Number + 1}, 
    io:format("Pong sent ping ~p to ~p~n", [Number, PidPing]), 
    ps5:loop_pong(); 
    {pong, {PidPing, PidPong}, Number} when Number >= 10-> 
    io:format("Pong received ~p on ~p~n and closing.~n", [Number, PidPing]); 
    Oops -> 
    io:format("Oops received: ~p~n", [Oops]), 
    ps5:loop_pong() 
    end. 

컴파일하는 동안 몇 가지 경고가 있습니다하지만이 문제에 대한 무관 (적어도 난 그렇게 생각) : 여기

는 코드입니다.

답변

6

구성 {Registered_process_name, Erlang_node} ! Some_message은 원격 등록 된 PID를 모르는 프로세스에 메시지를 보내는 데 사용됩니다.

{PidPong, ?NODE_TP} ! {pong, {PidPing, PidPong}, Number + 1}, 

PidPong ! {pong, {PidPing, PidPong}, Number + 1}, 

과에 : 귀하의 경우

당신은 당신이 {name, node} ! message 아니라 PID ! message 즉 변화를 사용하지해야한다는 것을 의미하는 PID를 알고 (그리고 프로세스가 등록되어 있지 않습니다)

{PidPing, ?NODE_AS} ! {ping, {PidPing, PidPong}, Number + 1}, 
PidPing ! {ping, {PidPing, PidPong}, Number + 1}, 
+0

믿기지 않을 정도로 간단했습니다! 이 "등록"을 놓친 것 같습니다. 차이점은 다른 노드의 등록 된 프로세스에 메시지를 보내는 방법입니다. {pong, Pong_Node}! {ping, self()}, 우리는 단지 registered_name 대신에 {registered_name, node_name} 튜플을 사용합니다. 감사합니다. – gljivar

관련 문제