Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何跨两个Erlang节点发送消息_Erlang - Fatal编程技术网

如何跨两个Erlang节点发送消息

如何跨两个Erlang节点发送消息,erlang,Erlang,我的两个Erlang模块中的代码如下所示: 接收者: start() -> PID = spawn(?MODULE, message_box, []), PID. message_box() -> sender:start_link(), receive {From, take_this_message} -> From ! "ok thanks !"; {From, fish} ->

我的两个Erlang模块中的代码如下所示:

接收者:

start() ->
    PID = spawn(?MODULE, message_box, []),
    PID.

message_box() ->
    sender:start_link(),
    receive
        {From, take_this_message} ->
            From ! "ok thanks !";
        {From, fish} ->
            From ! "So long and thanks for all the fish";
        _  ->
            io:format("Received Nothing~n")
        end.
发件人:

-module(sender).

-compile(export_all).

start_link() ->
    PID = spawn_link(?MODULE, init, [self()]),
    PID.

init(PID) ->
    PID ! {self(), "Wassup!"}.
我希望接收器在调用start_link()后显示未收到任何内容。 另外,如何使用shell或其他方式检查模块/进程在运行时收到的消息

**ERROR MESSAGE:**  

=ERROR REPORT==== 21-Jul-2014::12:42:44 ===
Error in process <0.40.0> with exit value: {undef,[{sender,start_link,[],[]},{receiver,message_box,0,[{file,"receiver.erl"},{line,14}]}]}
**错误消息:**
=错误报告===2014年7月21日::12:42:44===
使用退出值处理时出错:{unde,[{sender,start_link,[],[]},{receiver,message_box,0,[{file,“receiver.erl”},{line,14}]}

为了能够在两个节点之间交换消息,必须首先启动两个节点(erl-sname foo,erl-sname bar),将它们关联到集群中。这可以使用net\u adm:ping/1函数完成:
net\u adm:ping(foo@domain)在条形图节点上。
应返回pong。(如果您得到了pang,那么检查拼写,检查这两个节点是否具有相同的cookie)或net_kernel:connect(foo@domain)应该可以返回

然后,您可以在一个节点上启动接收方进程,并从第二个节点获取其Pid,例如
rpc:call(foo@domain,erlang,processs,[])。
将返回在节点foo上运行的所有进程的列表

然后,您可以在第二个节点上运行send函数,您将在shell消息队列中获得返回的消息

这是因为send函数使用self()给pid返回答案的位置,并且它在shell进程中运行(没有生成新进程)

如果生成的函数没有更改,返回消息将丢失,因为在发送第一条消息后,进程将立即终止。您需要修改它,例如:

-module(sender).

-compile(export_all).

init(PID,Mess) ->
    spawn(?MODULE,send_receive,[PID,Mess]).

send_receive(PID,Mess) ->
    PID ! {self(), Mess},
    R = receive
        M -> {ok,M}
    after 5000 -> {error,"no answer!"}
    end,
    io:format("~p~n",[R]).

-module (receiver).

-compile(export_all).

start() ->
    PID = spawn(?MODULE, message_box, []),
    PID.

message_box() ->
    receive
        {From, take_this_message} ->
            From ! "ok thanks !";
        {From, fish} ->
            From ! "So long and thanks for all the fish";
        _  ->
            io:format("Received Nothing~n")
        end.
在外壳中:

(foo@W7FRR00423L)3> receiver:start().
<0.50.0>
Received Nothing    
(foo@W7FRR00423L)4> receiver:start().
<0.53.0>
(foo@W7FRR00423L)5> receiver:start().
<0.55.0>
Received Nothing    
(foo@W7FRR00423L)6> 



(bar@W7FRR00423L)1> net_kernel:connect(foo@W7FRR00423L).
true
(bar@W7FRR00423L)2> nodes().
[foo@W7FRR00423L]
(bar@W7FRR00423L)3> rpc:call(foo@W7FRR00423L,erlang,processes,[]).
[<6075.0.0>,<6075.3.0>,<6075.6.0>,<6075.7.0>,<6075.9.0>,
 <6075.10.0>,<6075.11.0>,<6075.12.0>,<6075.13.0>,<6075.14.0>,
 <6075.15.0>,<6075.16.0>,<6075.17.0>,<6075.18.0>,<6075.19.0>,
 <6075.20.0>,<6075.21.0>,<6075.22.0>,<6075.23.0>,<6075.24.0>,
 <6075.25.0>,<6075.26.0>,<6075.27.0>,<6075.28.0>,<6075.29.0>,
 <6075.30.0>,<6075.31.0>,<6075.32.0>,<6075.33.0>|...]
(bar@W7FRR00423L)4> sender:init(pid(6075,50,0),take_this_message).
<0.55.0>
{error,"no answer!"}
(bar@W7FRR00423L)5> sender:init(pid(6075,53,0),take_this_message).
<0.57.0>
{ok,"ok thanks !"}  
(bar@W7FRR00423L)6> sender:init(pid(6075,55,0),"Wassup!").        
<0.59.0>
{error,"no answer!"}
(bar@W7FRR00423L)7>
然后使用语法{name,node}发送消息:
sender:init({receiver,bar@W7FRR00423L},记下这封信。

或者,您可以从一个节点创建两个进程,如下所示:

start() ->
    PID = spawn(?MODULE, message_box, []),
    register(?MODULE,PID),
    PID.
(foo@W7FRR00423L)4> Pid = rpc:call(bar@W7FRR00423L,receiver,start,[]).           
<5974.54.0> 
(foo@W7FRR00423L)5> sender:init(Pid,fish).
<0.50.0>
{ok,"So long and thanks for all the fish"}
(foo@W7FRR00423L)6>
(foo@W7FRR00423L)4> Pid=rpc:call(bar@W7FRR00423L,接收器,开始,[])。
(foo@W7FRR00423L)5> 发送方:init(Pid,fish)。
{好的,“再见,谢谢你的鱼”}
(foo@W7FRR00423L)6>

为了能够在两个节点之间交换消息,必须首先启动两个节点(erl-sname foo,erl-sname bar),将它们关联到集群中。这可以使用net\u adm:ping/1函数完成:
net\u adm:ping(foo@domain)在条形图节点上。
应返回pong。(如果您得到了pang,那么检查拼写,检查这两个节点是否具有相同的cookie)或net_kernel:connect(foo@domain)应该可以返回

然后,您可以在一个节点上启动接收方进程,并从第二个节点获取其Pid,例如
rpc:call(foo@domain,erlang,processs,[])。
将返回在节点foo上运行的所有进程的列表

然后,您可以在第二个节点上运行send函数,您将在shell消息队列中获得返回的消息

这是因为send函数使用self()给pid返回答案的位置,并且它在shell进程中运行(没有生成新进程)

如果生成的函数没有更改,返回消息将丢失,因为在发送第一条消息后,进程将立即终止。您需要修改它,例如:

-module(sender).

-compile(export_all).

init(PID,Mess) ->
    spawn(?MODULE,send_receive,[PID,Mess]).

send_receive(PID,Mess) ->
    PID ! {self(), Mess},
    R = receive
        M -> {ok,M}
    after 5000 -> {error,"no answer!"}
    end,
    io:format("~p~n",[R]).

-module (receiver).

-compile(export_all).

start() ->
    PID = spawn(?MODULE, message_box, []),
    PID.

message_box() ->
    receive
        {From, take_this_message} ->
            From ! "ok thanks !";
        {From, fish} ->
            From ! "So long and thanks for all the fish";
        _  ->
            io:format("Received Nothing~n")
        end.
在外壳中:

(foo@W7FRR00423L)3> receiver:start().
<0.50.0>
Received Nothing    
(foo@W7FRR00423L)4> receiver:start().
<0.53.0>
(foo@W7FRR00423L)5> receiver:start().
<0.55.0>
Received Nothing    
(foo@W7FRR00423L)6> 



(bar@W7FRR00423L)1> net_kernel:connect(foo@W7FRR00423L).
true
(bar@W7FRR00423L)2> nodes().
[foo@W7FRR00423L]
(bar@W7FRR00423L)3> rpc:call(foo@W7FRR00423L,erlang,processes,[]).
[<6075.0.0>,<6075.3.0>,<6075.6.0>,<6075.7.0>,<6075.9.0>,
 <6075.10.0>,<6075.11.0>,<6075.12.0>,<6075.13.0>,<6075.14.0>,
 <6075.15.0>,<6075.16.0>,<6075.17.0>,<6075.18.0>,<6075.19.0>,
 <6075.20.0>,<6075.21.0>,<6075.22.0>,<6075.23.0>,<6075.24.0>,
 <6075.25.0>,<6075.26.0>,<6075.27.0>,<6075.28.0>,<6075.29.0>,
 <6075.30.0>,<6075.31.0>,<6075.32.0>,<6075.33.0>|...]
(bar@W7FRR00423L)4> sender:init(pid(6075,50,0),take_this_message).
<0.55.0>
{error,"no answer!"}
(bar@W7FRR00423L)5> sender:init(pid(6075,53,0),take_this_message).
<0.57.0>
{ok,"ok thanks !"}  
(bar@W7FRR00423L)6> sender:init(pid(6075,55,0),"Wassup!").        
<0.59.0>
{error,"no answer!"}
(bar@W7FRR00423L)7>
然后使用语法{name,node}发送消息:
sender:init({receiver,bar@W7FRR00423L},记下这封信。

或者,您可以从一个节点创建两个进程,如下所示:

start() ->
    PID = spawn(?MODULE, message_box, []),
    register(?MODULE,PID),
    PID.
(foo@W7FRR00423L)4> Pid = rpc:call(bar@W7FRR00423L,receiver,start,[]).           
<5974.54.0> 
(foo@W7FRR00423L)5> sender:init(Pid,fish).
<0.50.0>
{ok,"So long and thanks for all the fish"}
(foo@W7FRR00423L)6>
(foo@W7FRR00423L)4> Pid=rpc:call(bar@W7FRR00423L,接收器,开始,[])。
(foo@W7FRR00423L)5> 发送方:init(Pid,fish)。
{好的,“再见,谢谢你的鱼”}
(foo@W7FRR00423L)6>

除了尝试和错误,还有其他方法来识别接收器的PID吗?通常您使用注册的进程,因此您可以按名称访问它们,如果必须重新启动进程,则名称保持不变。我将使用注册进程发布代码的更新版本。但是您的实现似乎更有用,比如,我想在receiver程序中创建一个指向发送方的链接。我应该将哪些参数传递给
spawn\u link/4
?在Erlang中,链接是一个双向连接,由系统管理,确保链接在一起的所有进程(如网格中)将一起消亡。如果您使用spawn_link/4,您将把调用进程与新生成的进程链接起来(例如,shell与接收方);这样做不需要任何参数。我猜您想要的是将发送者链接到接收者,在这种情况下,只需修改send\u receive函数,在开头添加:
link(PID),
然后发送者在第一条消息完成后,接收者将立即死亡!除了尝试和错误,还有其他方法来识别接收器的PID吗?通常您使用已注册的进程,因此您可以按名称访问它们,如果必须重新启动进程,则名称保持不变。我将使用注册进程发布代码的更新版本。但是您的实现似乎更有用,比如,我想在receiver程序中创建一个指向发送方的链接。我应该将哪些参数传递给
spawn\u link/4
?在Erlang中,链接是一个双向连接,由系统管理,确保链接在一起的所有进程(如网格中)将一起消亡。如果您使用spawn_link/4,您将把调用进程与新生成的进程链接起来(例如,shell与接收方);这样做不需要任何参数。我猜您想要的是将发送者链接到接收者,在这种情况下,只需修改send\u receive函数,在开头添加:
link(PID),
然后发送者在第一条消息完成后,接收者将立即死亡!