底下这个格式太难调了,最好拷到sublime上仔细看看
-module(ring).
-export([start/3]).
%取链表中第i个元素,从0开始
index(0,[H|_T])->H;
index(N,[_H|T])->index(N-1,T).
start(M,N,Msg) ->
RingList=ringList(N,[]),%进程环存储成链表
register(ring,spawn(fun()->ring_service(M,N,Msg,RingList) end)),
%先从第一个进程给第二个进程发消息
sendMsg(Msg,M,N,RingList,0,0,1).
ring_service(M,N,Msg,RingList) ->
receive
{start,Start} ->
%io:format("start:~w~n",[Start]),
io:format("~nStart from a new process:~w~n",[Start]),
sendMsg(Msg,M,N,RingList,Start,Start,(Start+1) rem N),
ring_service(M,N,Msg,RingList);
stop -> stop_ring(RingList)
end.
ringList(N,Ring) when N>0
->Next_Pid = spawn(fun() ->loop() end),
ringList(N-1,[Next_Pid|Ring]);
ringList(0,Ring) ->lists:reverse(Ring).
stop_ring([]) ->io:format("stop all~n");
stop_ring([H|T]) ->H!stop,
stop_ring(T).
%发消息
sendMsg(_Msg,0,N,_RingList,Start,_Src,_Dest)
when Start =:= (N-1)->
%io:format("stop all~n"),
ring!stop; %如果第N个进程发的消息传递完了的话
sendMsg(_Msg,0,_N,_RingList,Start,_Src,_Dest) ->
%io:format("~nStart from a new process:~w~n",[Start+1]),
ring!{start,Start+1}; %起点换下一个进程开始发消息
sendMsg(Msg,M,N,RingList,Start,Src,Dest) ->
index(Dest,RingList) ! {msg,Msg,M,N,RingList,Start,Src,Dest},
io:format("send message:~s from ~w to ~w ~n",[Msg,Src,Dest]).
%收消息
loop()->
receive
{msg,Msg,M,N,RingList,Start,Src,Dest} ->
io:format("receive message:~s from ~w~n",[Msg,Src]),
sendMsg(Msg,M-1,N,RingList,Start,(Src+1)rem N,(Dest+1)rem N),
loop();
stop ->true
end.