我正在尝试学习一些基本的Erlang,我想为这个有界缓冲区(旧的考试问题)编写一个测试程序,其中我有一个进程多次调用put函数,另一个进程调用get-method多次。我得到一个我不明白的错误。 这是有界缓冲区:
-module(bbuffer).
-export([start/1, get/1, put/2]).
%Creates new buffer of size N and returns its handle.
start(N) ->
spawn(fun () -> loop ([], N) end).
% L is the queue, N is the number of free slots
loop(L, N) ->
receive
{get, P, Ref} when L /= [] ->
[X|Xs] = L,
P ! {get_reply, Ref, X},
loop(Xs, N + 1);
{put, P, Ref, Y} when N > 0 ->
P ! {put_reply, Ref},
loop(L ++ [Y], N - 1)
end.
get(B) ->
Ref = make_ref(), %Unique value to identify messages
B ! {get, self(), Ref}, %Send message to process B
receive
{get_reply, Ref, X} -> X
end.
put(B, X) ->
Ref = make_ref(),
B ! {put, self(), Ref, X},
receive
{put_reply, Ref} -> ok
end.
这是我的代码:
-module(main).
-export([start/1]).
start(N) ->
Pid = bbuffer:start(N),
spawn(fun () -> insert(N, Pid) end),
spawn(fun () -> take(N, Pid) end).
insert(N, Pid) when N > 0 ->
io:format("INSERT ~n"),
bbuffer:put(Pid, N),
insert(N - 1, Pid).
take(N, Pid) when N > 0 ->
io:format("TAKE ~n"),
bbuffer:get(Pid),
take(N - 1, Pid).
这是我得到的错误:
Error in process <0.62.0> with exit value:
{function_clause,[{main,take,[-1,<0.60.0>],[{file,"main.erl"},{line,19}]}]}
Error in process <0.61.0> with exit value:
{function_clause,[{main,insert,[-1,<0.60.0>],[{file,"main.erl"},{line,13}]}]}
程序运行并循环N次但崩溃。有人可以解释为什么我的解决方案不起作用或提出另一个解决方案的想法?谢谢。
答案 0 :(得分:1)
您需要为递归函数take
和insert
创建一个不做任何事情的基础案例。如果没有任何子句匹配,Erlang不会忽略函数调用 - 它会使该进程崩溃并发生错误。
insert(N, Pid) when N > 0 ->
io:format("INSERT ~n"),
bbuffer:put(Pid, N),
insert(N - 1, Pid).
insert(_N, _Pid) ->
ok
take(N, Pid) when N > 0 ->
io:format("TAKE ~n"),
bbuffer:get(Pid),
take(N - 1, Pid).
take(_N, _Pid) ->
ok