我正在实施一个带2个入口大门的停车场和1个可以离开公园的停车场。对我来说,一切看起来都不错,但我遇到了错误,如
Error in process <0.84.0> with exit value: {badarg,[{parking,car,2},{random,uniform,0}]}
我的代码是:
-module (parking2).
-export ([start/3]).
-export ([car/2, parkingLoop/1]).
carsInit(0, _Iterations) ->
ok;
carsInit(Number, Iterations) ->
spawn(parking, car, [Number, Iterations]),
carsInit(Number - 1, Iterations).
car(_ID, 0) ->
ok;
car(ID, Iterations) ->
Gate = random:uniform(2),
parking ! {enter, self()},
receive
error ->
io:format("Car ~B ncanot enter - there is no free place.~n", [ID]),
Time = random:uniform(1000),
timer:sleep(Time),
car(ID, Iterations);
ok ->
io:format("Car ~B entered through the ~B gate~n", [ID, Gate])
end,
StopTime = random:uniform(500) + 500,
timer:sleep(StopTime),
parking ! {leave, self(), ID},
FreerideTime = random:uniform(1000) + 500,
timer:sleep(FreerideTime),
car(ID, Iterations - 1).
parkingInit(Slots) ->
spawn(parking, parkingLoop, [Slots]).
parkingLoop(Slots) ->
receive
{enter, Pid} ->
if Slots =:= 0 ->
Pid ! error
end,
Pid ! ok,
parkingLoop(Slots - 1);
{leave, Pid, ID} ->
io:format("Car ~B left the car park.", [ID]),
parkingLoop(Slots + 1);
stop ->
ok
end.
start(Cars, Slots, Iterations) ->
parkingInit(Slots),
carsInit(Cars, Iterations).
是的,有人能帮帮我吗?我学习Erlang几天,不知道,这里有什么不对。
提前致谢, 拉狄克
答案 0 :(得分:6)
您发布的示例在spawn/3
调用中使用了错误的模块:
spawn(parking, parkingLoop, [Slots]).
如果将其更改为:
,它应该可以更好地工作(或者至少提供更新的错误)spawn(?MODULE, parkingLoop, [Slots]).
(在执行此类操作时,始终使用?MODULE
,这是一个评估当前模块名称的宏,因为它可以避免使用错误模块导致的大量错误。
该错误来自未注册parkingLoop
进程。您正尝试使用parking ! ...
向其发送消息,但没有任何进程名为parking
。将第33行更改为:
register(parking, spawn(parking2, parkingLoop, [Slots])).
(即使在这里,您也可以使用?MODULE
宏来避免将来出现问题:?MODULE ! ...
和register(?MODULE, ...)
,因为您只有一个具有此名称的流程)
此外,第38行的if
语句错过了一个通过条款。使它看起来像这样处理Slots
等于零的情况:
if
Slots =:= 0 ->Pid ! error;
true -> ok
end,
(ok
表达式无效,因为未使用if
语句的返回值)