square1([]) -> [];
square1([X|Xs]) -> [X*X | square1(Xs)].
square2(Xs) -> [X*X || X <- Xs].
square3(Xs) -> lists:map(fun(X) -> X*X end, Xs).
filter1(_, []) -> [];
filter1(F, [X|Xs]) ->
case F(X) of
true -> [X|filter1(F, Xs)] ;
false -> filter1(F, Xs)
end.
filter2(_, []) -> [];
filter2(F, [X|Xs]) ->
Result = F(X),
if
Result -> [X|filter2(F, Xs)] ;
true -> filter2(F, Xs)
end.
filter3(F, Xs) -> [X || X <- Xs, F(X)].
avg_server1(Avg) ->
io:fwrite("Current average is ~p~n", [Avg]),
receive
Num -> avg_server1((Avg + Num) / 2)
end.
avg_server2() ->
receive
Num -> avg_server2([Num])
end.
avg_server2(Nums) ->
io:fwrite("The average of ~p is ~p~n", [Nums, sum(Nums) / length(Nums)]),
receive
Num -> avg_server2(Nums ++ [Num])
end.
sum([]) -> 0;
sum([X|Xs]) -> X + sum(Xs).
% Main server function
queue_server(Q) ->
receive
{Pid, push, Val} -> Pid ! ok, queue_server(Q ++ [Val]) ;
{Pid, pop} when length(Q) > 0 -> Pid ! hd(Q), queue_server(tl(Q))
end.
% API
new_queue() -> spawn(fun() -> queue_server([]) end).
push(Pid, Val) ->
Pid ! {self(), push, Val},
receive ok -> ok end.
pop(Pid) ->
Pid ! {self(), pop},
receive Val -> Val end.
Solution to Q1:
-module(sem).
-export([createSem/1, acquire/1, release/1]).
body(Val) ->
receive
{acquire, Pid} when Val > 0 ->
Pid ! ok,
body(Val - 1) ;
release ->
body(Val + 1)
end.
createSem(InitialValue) ->
spawn(fun() -> body(InitialValue) end).
acquire(Semaphore) ->
Semaphore ! {acquire, self()},
receive
ok -> ok
end.
release(Semaphore) ->
Semaphore ! release,
ok.
Solution to Q2:
-module(semtester).
-export([test/0]).
testN(N, Sem) ->
sem:acquire(Sem),
io:fwrite("~p in~n", [N]),
timer:sleep(500),
io:fwrite("~p out~n", [N]),
sem:release(Sem),
testN(N, Sem).
test() ->
Sem = sem:createSem(1),
lists:foreach(
fun(N) -> spawn(fun() -> testN(N, Sem) end) end,
lists:seq(1,5)
).
Solution to Q1:
New function loop/1
needs to be defined, while the definition of loop/0
needs to be changed to call loop/1
.
loop() -> loop([]).
loop(Buffer) when length(Buffer) >= 10 ->
net_io:transmit(Buffer),
loop([]);
loop(Buffer) ->
receive
{request, Pid, Ref, {send, Msg}} ->
Pid ! {result, Ref, ok},
loop(Buffer ++ [Msg])
end.
Solution to Q2:
The definitions of the loop/0
and loop/1
should be replaced with the following definitions of loop/0
and loop/2
.
loop() ->
receive
{request, Pid, Ref, {send, Msg}} ->
Pid ! {result, Ref, ok},
Self = self(),
RefT = make_ref(),
spawn(fun () ->
receive after 100 -> Self!{timeout, RefT} end
end),
loop([Msg], RefT)
end.
loop(Buffer, _) when length(Buffer) >= 10 ->
transmit(Buffer),
loop();
loop(Buffer, RefT) ->
receive
{request, Pid, Ref, {send, Msg}} ->
Pid ! {result, Ref, ok},
loop(Buffer ++ [Msg], RefT);
{timeout, RefT} ->
transmit(Buffer),
loop()
end.
Here make_ref()
is used to make sure that we do not receive old timeout messages. This might be handled in some other way, but it is required to address this problem.