Radek
Radek

Reputation: 135

Problem with process creation

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

Answers (1)

Adam Lindberg
Adam Lindberg

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

Related Questions