【发布时间】:2018-11-29 00:53:28
【问题描述】:
我正在尝试理解 erlang 中的进程通信。这里我有一个主进程和五个好友进程。如果朋友向其他 5 个中的任何一个发送消息,他们必须回复。但是主人应该知道这一切。我正在粘贴下面的代码。
-module(prog).
-import(lists,[append/2,concat/1]).
-import(maps,[from_lists/1,find/2,get/2,update/3]).
-import(string,[equal/2]).
-import(file,[consult/1]).
-export([create_process/1,friends/4, master/1, main/0,prnt/1]).
%% CREATE PROCESS
create_process([])->ok;
create_process([H|T])->
{A,B} = H,
Pid = spawn(prog,friends,[B,self(),0,A]),
register(A,Pid),
create_process(T).
%% FRIENDS PROCESS
friends(Msg, M_pid, State, Self_name)->
S = lists:concat([Self_name," state =",State,"\n"]),
io:fwrite(S),
if
State == 0 ->
timer:sleep(500),
io:fwrite("~p~n",[Self_name]),
lists:foreach(fun(X) -> whereis(X)!{Self_name,"intro",self()} end, Msg),
friends(Msg, M_pid, State + 1, Self_name);
State > 0 ->
receive
{Process_name, Process_msg, Process_id} ->
I = equal(Process_msg,"intro"),
R = equal(Process_msg,"reply"),
XxX = lists:concat([Self_name," recieved ",Process_msg," from ",Process_name,"\n"]),
io:fwrite(XxX),
if
I == true ->
io:fwrite("~p~n",[whereis(Process_name)]),
M_pid!{lists:concat([Self_name," received intro message from ", Process_name , "[",Process_id,"]"]), self()},
io:fwrite(I),
whereis(Process_name)!{Self_name, "reply",self()},
friends(Msg, M_pid, State + 1, Self_name);
R == true ->
M_pid!{lists:concat([Self_name," received reply message from ", Process_name , "[",Process_id,"]"]), self()},
io:fwrite(R),
friends(Msg, M_pid, State + 1, Self_name)
end
after
1000->
io:fwrite(lists:concat([Self_name," has received no calls for 1 second, ending..."]))
end
end.
master(State)->
receive
{Process_message, Process_id} ->
io:fwrite(Process_message),
master(State+1)
after
2000->
ok
end.
main() ->
B = [{john, [jill,joe,bob]},
{jill, [bob,joe,bob]},
{sue, [jill,jill,jill,bob,jill]},
{bob, [john]},
{joe, [sue]}],
create_process(B),
io:fwrite("~p~n",[whereis(sue)]),
master(0).
我认为friends()函数中的那一行,
M_pid!{lists:concat([Self_name," received intro message from ", Process_name , "[",Process_id,"]"]), self()}
是错误的原因,但我不明白为什么。 M_pid 是已知的,我正在连接所有信息并将其发送给 master,但我很困惑为什么它不起作用。
我得到的错误如下:
Error in process <0.55.0> with exit value: {function_clause,[{lists,thing_to_list,
[<0.54.0>],
[{file,"lists.erl"},{line,603}]},
{lists,flatmap,2,[{file,"lists.erl"},{line,1250}]},
{lists,flatmap,2,[{file,"lists.erl"},{line,1250}]},
{prog,friends,4,[{file,"prog.erl"},{line,45}]}]}
我不知道是什么导致了错误。很抱歉向菜鸟提问,感谢您的帮助。
【问题讨论】:
-
尝试在对
lists:concat/2的调用中将Process_id更改为pid_to_list(Process_id)。 -
嗨,Dogbert。我会回家试一试。但出于好奇,有什么区别?为什么 Process_id 搞砸了 list:concat/2 ?
-
您报告的错误消息看起来与代码段不一致(第 45 行或其他任何地方没有列表:flatmap/2 调用)。我有 2 条评论: 1/ 你在 after 子句中没有递归调用,所以如果一个进程遇到这个子句,它将停止。 2/ 使用 import 指令是非常不寻常的,通常,erlang 程序员更喜欢显式显示完全限定的调用(就像你一样),在这种情况下 import 指令是无用的。
标签: functional-programming erlang