Reputation: 135
I am implementing a car park with 2 entry gates and 1 by which you can leave the park. For me, everything looks fine but I am getting errors like
Error in process <0.84.0> with exit value: {badarg,[{parking,car,2},{random,uniform,0}]}
My code is:
-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).
May anybody help me ? I learn Erlang for a couple of days and have no idea, what's wrong here.
Thanks in advance, Radek
Upvotes: 1
Views: 165
Reputation: 16577
The example you posted uses the wrong module in the spawn/3
call:
spawn(parking, parkingLoop, [Slots]).
It should work better (or at least give a more up to date error) if you change this to:
spawn(?MODULE, parkingLoop, [Slots]).
(Always use ?MODULE
, which is a macro that evaluates to the current module name, when doing such things since it will avoid a lot of mistakes using the wrong module than intended).
The bug comes from not registering the parkingLoop
process. You're trying to send a message to it using parking ! ...
but no process is named parking
. Change line 33 to:
register(parking, spawn(parking2, parkingLoop, [Slots])).
(Even here you can use the ?MODULE
macro to avoid problems in the future: ?MODULE ! ...
and register(?MODULE, ...)
since you only have one process with this name)
Also, your if
statement on line 38 misses a fall-through clause. Make it look like this to handle the case where Slots
is not equal to zero:
if
Slots =:= 0 ->Pid ! error;
true -> ok
end,
(The ok
expression will have no effect since the return value of the if
statement is not used)
Upvotes: 6