책 "Programming Erlang" 에서 8.11에 나오는 과제 2번 링 벤치마크(Ring Tester).
오랫만에 즐겁게 머리써봤다.
다른사람이 만든건 어떨지 궁금하다.
=== 역시 내가 만든건 여러모로 부족했다. OTL
만성피로님의 Ring Benchmark프로세스들의 고리를 만드는 방법이 감탄을 자아낸다.
또한
류준호님의 Ring Benchmark 역시 깔끔하다.
역시 다른사람 소스보는것이 더 재미있다.
아래는 부끄러운 내 소스
more..
-module (ring_test).
-compile(export_all).
% 기본 프로세스 10개
start() ->
start(10).
start(N) ->
case is_pid(whereis(ring_tester)) of
true ->
unregister(ring_tester) ;
false ->
void
end,
register(ring_tester, spawn(fun() -> spawn_proc(N) end)).
% ring_tester ! trace,
% ring_tester ! start.
% N개의 프로세스 생성
spawn_proc(N) ->
spawn_proc(N, []).
% 모두 만들었으면 대기.
spawn_proc(0, Procs) ->
wait_for_test(Procs);
spawn_proc(N, Procs) ->
spawn_proc(N-1, [spawn(fun() -> wait() end)|Procs]).
% 생성된 프로세스
wait() ->
receive
{ring_test, [], N} ->
io:format("Test Success! total message occured, ~p~n", [N]),
wait();
{ring_test, [Pid|Procs]} ->
N = 1,
io:format("start ring test, starts~p~n",[Pid]),
% io:format("test received ~p, Next ~p Messages ~p~n", [self(), Pid, N]),
Pid ! {ring_test, Procs, N + 1},
wait();
{ring_test, [Pid|Procs], N} ->
% io:format("test received ~p, Next ~p Messages ~p~n", [self(), Pid, N]),
Pid ! {ring_test, Procs, N + 1},
wait();
_Debug ->
io:format("Debugging, ~p~n", [_Debug])
end.
% main(?) 프로세스?
wait_for_test(Procs) ->
receive
destroy ->
unregister(ring_tester),
void;
trace ->
trace_list(Procs),
wait_for_test(Procs);
start ->
[Pid|TailPids] = Procs,
Pid ! {ring_test, TailPids},
wait_for_test(Procs)
end.
trace_list(List) ->
lists:map(fun(I) -> io:format("~p~n", [I]) end, List).