-
Notifications
You must be signed in to change notification settings - Fork 5
/
bbp_proc.erl
114 lines (99 loc) · 3.18 KB
/
bbp_proc.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
-module(bbp_proc).
-compile([export_all]).
% Concurent Proccess Excercises
% http://www.erlang.org/course/exercises.html
% Two-way messenger
init_two_way_messages() ->
Pid1 = spawn(fun two_way_messenger/0),
Pid2 = spawn(fun two_way_messenger/0),
Pid1 ! {"the_message", 5, Pid2}.
two_way_messenger() ->
receive
{Msg, 0, Pid} ->
Pid ! {Msg, 0, self()},
exit(done);
{Msg, Num, Pid} ->
io:format("message from ~w ~w~n", [Pid, Num]),
Pid ! {Msg, Num - 1, self()},
two_way_messenger();
_ ->
two_way_messenger()
end.
% Ring
init_ring(NumMembers, NumMessages) ->
Members = spawn_members(NumMembers),
io:fwrite("Starting ring with members "),
lists:foreach(fun (I) -> io:fwrite("~w -> ", [I]) end, Members),
io:fwrite("~n"),
[Pid1|_] = Members,
Pid1 ! {msg, NumMessages}.
spawn_members(NumMembers) when NumMembers > 1 ->
First = spawn_member(),
spawn_members(NumMembers-1, [First]).
spawn_members(0, [First|Tail]) ->
First ! {set_next, lists:last(Tail)},
[First|Tail];
spawn_members(Num, Members) ->
Member = spawn_member(lists:last(Members)),
spawn_members(Num-1, Members ++ [Member]).
spawn_member() -> spawn(fun nextless_ring_member/0).
spawn_member(Pid) ->
spawn(fun () -> ring_member(Pid) end).
nextless_ring_member() ->
receive
{set_next, Next} -> ring_member(Next);
_ -> nextless_ring_member()
end.
ring_member(Next) ->
receive
{msg, 0} -> io:fwrite("~nDone!~n"), exit(done);
{msg, Count} ->
io:fwrite("~w ~w~n", [Count, self()]),
Next ! {msg, Count-1},
ring_member(Next);
_ -> ring_member(Next)
end.
% Star
init_star(NumProc, NumMsg) ->
Pid = spawn(fun () -> star_supervisor(NumProc * NumMsg, 0) end),
io:fwrite("Star's Pid: ~w~n", [Pid]),
Pid ! {start, NumProc, NumMsg}.
star_supervisor(Limit, Current) when Limit == Current ->
io:fwrite("Sup quitting, all done~n"),
exit(done);
star_supervisor(Limit, Current) ->
receive
{start, NumProc, NumMsg} ->
Children = star_children(self(), NumProc),
io:fwrite("Made ~w children~n", [length(Children)]),
star_send_messages(Children, NumMsg),
star_supervisor(Limit, Current);
{msg, Pid} ->
io:fwrite("Received message ~w from pid ~w~n", [msg,Pid]),
star_supervisor(Limit, Current+1);
_-> star_supervisor(Limit, Current)
end.
star_children(Sup, NumProc) ->
First = spawn(fun () -> star_child(Sup) end),
star_children(Sup, NumProc-1, [First]).
star_children(Sup, 1, Children) ->
Child = spawn(fun () -> star_child(Sup) end),
Children ++ [Child];
star_children(Sup, NumProc, Children) ->
Child = spawn(fun () -> star_child(Sup) end),
star_children(Sup, NumProc-1, Children ++ [Child]).
star_child(Sup) ->
receive
{stop} -> exit(done);
{msg} ->
Sup ! {msg, self()},
star_child(Sup);
_ -> star_child(Sup)
end.
star_send_messages(Children, 0) ->
io:fwrite("Stopping children~n", []),
lists:foreach(fun (Child) -> io:fwrite("."), Child ! {stop} end, Children);
star_send_messages(Children, NumMsg) ->
io:fwrite("Sending message ~w~n", [NumMsg]),
lists:foreach(fun (Child) -> io:fwrite("."), Child ! {msg} end, Children),
star_send_messages(Children, NumMsg-1).