创建流程的问题

Rad*_*dek 1 erlang

我正在实施一个带2个入口大门的停车场和1个可以离开公园的停车场.对我来说,一切看起来都不错,但我得到的错误就像

Error in process <0.84.0> with exit value: {badarg,[{parking,car,2},{random,uniform,0}]}
Run Code Online (Sandbox Code Playgroud)

我的代码是:

-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).
Run Code Online (Sandbox Code Playgroud)

愿有人帮帮我吗?我学习Erlang几天,不知道,这里有什么不对.

谢谢,拉德克

Ada*_*erg 6

您发布的示例在spawn/3调用中使用了错误的模块:

spawn(parking, parkingLoop, [Slots]).
Run Code Online (Sandbox Code Playgroud)

如果将其更改为:它应该更好(或至少提供更新的错误)

spawn(?MODULE, parkingLoop, [Slots]).
Run Code Online (Sandbox Code Playgroud)

(总是使用?MODULE,这是一个评估当前模块名称的宏,在执行此类操作时,因为它将避免使用错误模块的错误而非预期).

该错误来自未注册该parkingLoop过程.您正在尝试使用它向其发送消息,parking ! ...但未命名任何进程parking.将第33行更改为:

register(parking, spawn(parking2, parkingLoop, [Slots])).
Run Code Online (Sandbox Code Playgroud)

(即使在这里,你可以使用?MODULE宏来避免未来的问题:?MODULE ! ...register(?MODULE, ...),因为你只有一个进程使用这个名称)

另外,你if在第38行的陈述错过了一个通过条款.使它看起来像这样来处理情况的情况下Slots等于零:

if 
    Slots =:= 0 ->Pid ! error;
    true -> ok
end,
Run Code Online (Sandbox Code Playgroud)

(ok由于if未使用语句的返回值,表达式将无效)