Jestem nowy w firmie Erlang i próbuję zaprogramować program problemowy z ograniczonym buforem. To prawie działa, z wyjątkiem upewnienia się, że producenci nie posuną się zbyt daleko i nie zastąpią niepotrzebnych danych. Aby sobie z tym poradzić, postanowiłem spróbować umieścić strażników na mojej funkcji buffer(), tak, żebym mógł mieć wersję bez odbioru, gdy bufor jest pełny, wersja bez wysyłania, gdy bufor jest pusty, i normalna wersja do końca czasu.Nie można użyć wywołania funkcji w funkcji ochrony
Mój problem polega na tym, że ochrona dla wersji bez amplitunera wymaga ode mnie znajomości rozmiaru tablicy reprezentującej bufor, która wymaga wywołania do array:size/1
. Wygląda na to, że Erlang nie zezwala na wywoływanie funkcji w strażnikach, co uniemożliwia takie działanie. Czy jest jakiś sposób obejścia tego bez zmiany deklaracji funkcji dla mojego aktora bufora?
%% buffer: array num num
%% A process that holds the shared buffer for the producers and consumers
buffer(Buf, NextWrite, NextRead) when NextWrite == NextRead ->
io:format(" * ~w, ~w, ~w~n", [array:to_list(Buf), NextRead, NextWrite]),
receive
{enqueue, Reply_Pid, Num} ->
io:format("~w: > ~w~n", [Reply_Pid, Num]),
buffer(array:set(NextWrite rem array:size(Buf), Num, Buf), NextWrite + 1, NextRead);
finish ->
io:format("finished printing~n")
end;
buffer(Buf, NextWrite, NextRead) when (NextWrite - NextRead) == array:size(Buf) ->
io:format(" * ~w, ~w, ~w~n", [array:to_list(Buf), NextRead, NextWrite]),
receive
{dequeue, Reply_Pid} ->
io:format("~w: < ~w~n", [Reply_Pid, array:get(NextRead rem array:size(Buf), Buf)]),
Reply_Pid ! {reply, array:get(NextRead rem array:size(Buf), Buf)},
buffer(Buf, NextWrite, NextRead + 1);
finish ->
io:format("finished printing~n")
end;
buffer(Buf, NextWrite, NextRead) ->
io:format(" * ~w, ~w, ~w~n", [array:to_list(Buf), NextRead, NextWrite]),
receive
{dequeue, Reply_Pid} ->
io:format("~w: < ~w~n", [Reply_Pid, array:get(NextRead rem array:size(Buf), Buf)]),
Reply_Pid ! {reply, array:get(NextRead rem array:size(Buf), Buf)},
buffer(Buf, NextWrite, NextRead + 1);
{enqueue, Reply_Pid, Num} ->
io:format("~w: > ~w~n", [Reply_Pid, Num]),
buffer(array:set(NextWrite rem array:size(Buf), Num, Buf), NextWrite + 1, NextRead);
finish ->
io:format("finished printing~n")
end.
To jest ładne, proste i łatwe do zrozumienia. Dzięki. –
Hi @Geoff, Czy znasz sposób na porównanie dwóch ciągów jako strażnika ?. np. - funkcja gdy string: equals (string1, string2) -> 1. –
@DenisWeerasiri Jestem całkiem pewny, że 'string: equals/2' jest identyczny z' == ', więc możesz go użyć w straży . –