这个代码主要是参考同学的这篇博客:http://blog.csdn.net/mutx_lck/article/details/45603767,并在此基础上增添了发送方的验证。
-module (exe7).
-export ([start/2,handle/6,partition/1,list_length/1]).
start (Data,M) ->
Pid= spawn(?MODULE,handle,[Data,M,M,1,self(),[0]]).
%首先对每个核排序,然后将结果合并
handle(Data,M,Processnum,Id,Master,L) ->
{List,Res} = para_qsort(Data,M,Processnum,Id,Master,L),
Len = list_length(List),
%io:format("id:~w L:~w Res:~w ~n",[Id,List,Res]),
merge(Res,Master,Id,2,Processnum,List,Len,1).
%进程间通讯
merge(Res,Master,Id,Judge,M,L,Len,K) when M =:= 1 ->
io:format("result : ~w ~n",[Res]);
merge(Res,Master,Id,Judge,M,L,Len,K) ->
Get = lists:nth(K,L),
if
Id rem Judge =:= 1 ->
receive
{Get,OtherRes} ->
io:format("~w receive ~w from ~w ~n",[Id,OtherRes,Get]),
NewRes = lists:append(Res,OtherRes),
merge(NewRes,Master,Id,Judge*2,M div 2,L,Len,K+1)
end;
true ->
Master ! {Id,Res}
end.
%并行快排,这里Id和Master一一对应,便于将结果返回,
%比如当M=8时,首先核1创建核5,并将核1的进程id当做参数
%传递给核5,其中L是每个核创新核的Id序列,每个核按此序列收集结果。
para_qsort(Data,M,Start,Id,Master,L) ->
if M =:= 1->
%io:format("id:~w L:~w ~n",[Id,L]),
List = lists:reverse(L),
NewData = lists:sort(Data),
{List,NewData};
true ->
{FrontPart,BehindPart} = partition(Data),
Child_Pid = Id+(M div 2),
spawn(?MODULE,handle,[BehindPart,M div 2,Start,Child_Pid,self(),[0]]),
para_qsort(FrontPart,M div 2,Start,Id,Master,L++[Child_Pid])
end.
list_length([]) -> 0;
list_length([H|T]) ->1+list_length(T).
partition([]) ->{[],[]};
partition([H|T]) -> Length = list_length([H|T]),
if Length =:= 1 ->{[H],[]};
true -> {[X || X <- [H|T] , X =< H],[Y || Y <- [H|T] , Y > H]}
end.