Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.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_Erlang Shell - Fatal编程技术网

如何向Erlang中的进程列表广播消息?控制台悬挂

如何向Erlang中的进程列表广播消息?控制台悬挂,erlang,erlang-shell,Erlang,Erlang Shell,我是Erlang的新手,我试图了解如何将消息从一个进程发送到一个进程列表 假设我们有一个数据结构,其中包含一个包含字符串和Pid的元素的列表。如何使Pid向前面描述的两个元素之一的Pid发送消息“M”? 我想到的是: broadcast(P, M, R) -> P ! {self(), friends}, receive {P, Friends} -> P ! {self(), {send_message, {M, R, P, Friends}}} end.

我是Erlang的新手,我试图了解如何将消息从一个进程发送到一个进程列表

假设我们有一个数据结构,其中包含一个包含字符串和Pid的元素的列表。如何使Pid向前面描述的两个元素之一的Pid发送消息“M”? 我想到的是:

broadcast(P, M, R) ->
  P ! {self(), friends},
  receive
    {P, Friends} ->
  P ! {self(), {send_message, {M, R, P, Friends}}}
  end.

looper({Name, Friends, Messages}) ->
receive
  {From, friends} ->
    From ! {self(), Friends},
    looper({Name, Friends, Messages});
  {From, {send_message, {M, R, ID, [{FriendPid, FriendName} | FriendTale]}}} ->
    if R =< 0 ->
          From ! {From, {self(), {ID, M}}},
          looper({Name, [{FriendPid, FriendName} | FriendTale], [{ID, M} | Messages]});
       R > 0  andalso FriendTale =/= []->
         FriendPid ! {From, {send_message, {M, R-1, ID, FriendTale}}},
         looper({Name, FriendTale, [{ID, M} | Messages]})
    end;
   terminate ->
    ok
end.
其中“M”是我想要广播到称为“Friends”的PID列表的消息,R只是一个整数

R基本上是一个整数,表示消息应该走多远

e.g. 0 = broadcast the message to self,
     1 = broadcast the message to the friends of the pid,
     2 = broadcast the message to the friends of the friends of the pid and so on...
在设置Pid、设置Pid之间的“友谊”并广播消息后,我从终端获得的信息是:

1> f().
ok
2> c(facein).
facein.erl:72: Warning: variable 'From' is unused
{ok,facein}
3> {Message, Pid} = facein:start({"dummy", [], []}).
{ok,<0.186.0>}
4> {Message, Pid2} = facein:start({"dummy2", [], []}).
{ok,<0.188.0>}
5> facein:add_friend(Pid,Pid2).
ok
6> facein:broadcast(Pid,"hello",1).    
=ERROR REPORT==== 5-Oct-2014::12:12:58 ===
Error in process <0.186.0> with exit value: {if_clause,[{facein,looper,1,[{file,"facein.erl"},{line,74}]}]}

{<0.177.0>,{send_message,{"hello",1,#Ref<0.0.0.914>}}}
1>f()。
好啊
2> c(面内)。
facein.erl:72:警告:变量“From”未使用
{好的,facein}
3> {Message,Pid}=facein:start({“dummy”,[],[]})。
{好的,}
4> {Message,Pid2}=facein:start({“dummy2”,[],[]})。
{好的,}
5> facein:添加朋友(Pid,Pid2)。
好啊
6> facein:广播(Pid,“你好”,1)。
=错误报告===2014年10月5日::12:12:58===
使用退出值进行处理时出错:{if_子句,[{facein,looper,1,[{file,“facein.erl”},{line,74}]}
{,{发送消息,{“你好”,1,{Ref}}
当我查看广播消息的Pid的消息时,控制台只是挂起,其他Pid没有收到消息

任何帮助都将不胜感激。 谢谢

错误消息 这一次您得到的是
if_子句
错误。在Erlang中,如果包含
,则每个表达式都必须返回一些值。这意味着您可以编写这样的代码

SomeVar = if 
     R =< 0 ->
       [...]
     R > 0 andalso FriendTale =/= []->
       [...]
  end
这将始终匹配,并使您免于此类错误

在您的示例中,如果
,则根本不必使用
。你所能做的就是用一些警卫延长你收到的条款

looper({Name, Friends, Messages}) ->
  receive
    {From, {send_message, {M, R, ID, [{FriendPid, FriendName} | FriendTale]}}} 
       when R =< 0 ->
          From ! {From, {self(), {ID, M}}},
          looper({Name, [{FriendPid, FriendName} | FriendTale], [{ID, M} | Messages]});
    {From, {send_message, {M, R, ID, [{FriendPid, FriendName} | FriendTale]}}}  
       when R > 0  andalso FriendTale =/= [] ->
          FriendPid ! {From, {send_message, {M, R-1, ID, FriendTale}}},
          looper({Name, FriendTale, [{ID, M} | Messages]});
    terminate ->
          ok
  end.
为了增加可读性,您可以将
R
从opque integer更改为miningfull原子

looper({Name, Friends, Messages}) ->
  receive
    {From, {send_message, {M, back_to_me, ID, [{FriendPid, FriendName} | FriendTale]}}} ->
          From ! {From, {self(), {ID, M}}},
          looper({Name, [{FriendPid, FriendName} | FriendTale], [{ID, M} | Messages]});

    {From, {send_message, {M, to_friends, ID, [{FriendPid, FriendName} | FriendTale]}}}  
       when FriendTale =/= [] ->
          FriendPid ! {From, {send_message, {M, R-1, ID, FriendTale}}},
          looper({Name, FriendTale, [{ID, M} | Messages]});

    terminate ->
          ok
  end.
向朋友广播 如果我理解正确的话,
looper
是表示一个“人”的函数。每个好友都是一个进程,它存储好友列表,可以在其中添加和删除好友,还可以向其他好友发送消息

让我们从为每个函数创建子句开始(创建流程接口)

其中大多数都很容易实现,比如

{add_frined, Friend} ->
    looper(Name, [Friend, Friends], Messages);
因此,我不会详细说明

做广播的不会改变状态,所以现在让我们写一些类似的东西(主要是为了可读性)

     {broadcast_to_friends, Message} ->
        handle_broadcast_to_friends(Friends, Message),
        looper(Name, Friends, Messages);
并实现下面的新功能

handle_broadcast_to_friends(Friends, Message) ->
   [ F ! {receive_message, Message} || F <- Friends ].
我们也可以在逻辑实现中使用它们

handle_broadcast_to_friends(Friends, Message) ->
   [ receive_message(F, Message)  || F <- Friends ].
handle\u broadcast\u\u\u to\u friends(朋友,消息)->

[接收信息(F,信息)| | F我建议您先将所做工作的复杂性降低到基本内容。例如,接收中的条件处理业务不是基本消息传递问题的一部分。下面是一个常见广播习惯用法的基本示例,使用列表理解发送到函数
bcast/2 :

-module(bcast).
-export([start/0]).

start() ->
    Pids = [spawn(fun() -> listener() end) || _ <- lists:seq(1,3)],
    Message = "This is my message.",
    ok = bcast(Pids, Message),
    timer:sleep(100), % Give the subordinates time to act.
    [exit(P, kill) || P <- Pids],
    ok.

listener() ->
    receive
        {bcast, Message} ->
            Now = now(),
            io:format(user, "~p ~p: Received: ~p~n", [self(), now(), Message]),
            listener();
        Any ->
            io:format(user, "~p HURR! Unexpected message: ~p~n", [self(), Any]),
            listener()
    end.

bcast(Pids, Message) ->
    [P ! {bcast, Message} || P <- Pids],
    ok.
-模块(bcast)。
-导出([start/0])。
开始()->
Pids=[spawn(fun()->listener()end)| |
Now=Now(),
io:格式(用户,“~p~p:Received:~p~n”,[self(),now(),Message]),
监听器();
任何->
io:格式(用户,“~p HURR!意外消息:~p~n”,[self(),Any]),
监听器()
结束。
bcast(Pids,消息)->

[P!{bcast,Message}| | P此处不够详细,循环器函数甚至不是有效的erlang(缺少接收)。我在循环器中添加了接收(我的坏)。您还需要什么其他信息?也许我可以告诉您,但是我的语法是否正确,可以尝试将消息传递到进程列表?我在接收块中添加了另一个模式,因为再次看到错误报告,它提到的第74行是这一行:
From!{self(),Friends},
     {broadcast_to_friends, Message} ->
        handle_broadcast_to_friends(Friends, Message),
        looper(Name, Friends, Messages);
handle_broadcast_to_friends(Friends, Message) ->
   [ F ! {receive_message, Message} || F <- Friends ].
add_friend(Person,  Friend) ->
   Person ! {add_friend, Friends}.

receive_message(Person, Message) ->
    Person ! {receive_message, Message}.
handle_broadcast_to_friends(Friends, Message) ->
   [ receive_message(F, Message)  || F <- Friends ].
-module(bcast).
-export([start/0]).

start() ->
    Pids = [spawn(fun() -> listener() end) || _ <- lists:seq(1,3)],
    Message = "This is my message.",
    ok = bcast(Pids, Message),
    timer:sleep(100), % Give the subordinates time to act.
    [exit(P, kill) || P <- Pids],
    ok.

listener() ->
    receive
        {bcast, Message} ->
            Now = now(),
            io:format(user, "~p ~p: Received: ~p~n", [self(), now(), Message]),
            listener();
        Any ->
            io:format(user, "~p HURR! Unexpected message: ~p~n", [self(), Any]),
            listener()
    end.

bcast(Pids, Message) ->
    [P ! {bcast, Message} || P <- Pids],
    ok.