rapsoulCecil
rapsoulCecil

Reputation: 117

Erlang multiprocessing messages receiving and sending

I'm studying the book "Learn you some Erlang".I have a couple of questions to implement on multiprocessing programming with Erlang. Basically, I was reading and imitating "Learn you some Erlang". And I have generated a program with some oriented functions in my program. It said fridge can be acted like itself to store and take. So I'm processing my program for some operations in a base obeyed followings:

I'm totally confused about the usage of fridge itself. I've figured something like below with the sample code from tutorial:

-module(kitchen).
-compile(export_all).

fridge1() ->
receive
    {From, {store, _Food}} ->
        From ! {self(), ok},
        fridge1();
    {From, {take, _Food}} ->
        %% uh ...
        From ! {self(), not_found},
        fridge1();
    terminate             ->
            ok
end.

fridge2(FoodList) ->                        
receive
    {From, {store, Food}} ->
        From ! {self(), ok},
        fridge2( [Food | FoodList] );       
    {From, {take, Food}} ->
        case lists:member(Food, FoodList) of
            true   ->
                From ! {self(), {ok, Food}},
                fridge2(lists:delete(Food, FoodList));      
            false  ->
                From ! { self(), not_found},                    
                fridge2(FoodList)                           
            end;
    terminate            ->
        ok
end. 

store(Pid, Food) ->
Pid ! {self(), {store, Food}},
receive
    {Pid, Msg} -> Msg
end.

take(Pid, Food) ->
Pid ! {self(), {take, Food}},
receive 
    {Pid, Msg} -> Msg
end.

start(FoodList) ->
spawn(?MODULE, fridge2, [FoodList]).

Besides, here's some problems I've been thinking:

  1. How could I create a fridge process? Or it's already there?

  2. How could I create a cook process, passing it the fridge process pid?

  3. How could I store item to the fridge then sleep for several seconds and eventually I could take an item out from the fridge?

It's perhaps not the most complex problem, but I could not find any documentation about this so I'd appreciate some of you might know the answer.

Upvotes: 3

Views: 315

Answers (1)

Paulo Suassuna
Paulo Suassuna

Reputation: 131

Answering your questions:

  1. How could I create a fridge process? Or it's already there?

Once you call kitchen:start/1 from erlang shell or from another module, function spawn(?MODULE, fridge2, [FoodList]) will spawn a process for you. Take a look at the documentation for more details: http://www.erlang.org/doc/man/erlang.html#spawn-3

  1. How could I create a cook process, passing it the fridge process pid?

As I said in the first answer, spawn/3, which take a module, a function and arguments as parameters, is one of the functions you can use to spawn new processes. So, you should use it to spawn a process that receives kitchen:fridge2/1 pid as argument, something like

Kitchen = kitchen:start([]),
Cook = spawn(cook_module, cook_function, [Kitchen]).

That way you will spawn a process which executes cook_module:cook_function/1 and pass Kitchen (fridge pid) as the argument.

  1. How could I store item to the fridge then sleep for several seconds and eventually I could take an item out from the fridge?

You can store items to the fridge using the store/2 function, wait a bit (or several seconds, as you wish) and then, using the take/2 function, take something out the fridge. Just like this:

Pid = kitchen:start([]), %% this will spawn a fridge process
kitchen:store(Pid, "delicious insect pie"), %% this will store a delicious insect pie in your fridge by executing the function fridge2( [Food | FoodList] );
timer:sleep(1000), %% this function will make the caller process sleeps for 1000 milliseconds (you can change it for your several seconds instead...)
kitchen:take(Pid, "delicious insect pie"). %% this will take the delicious insect pie out of the fridge, by executing the function fridge2(lists:delete(Food, FoodList));

Upvotes: 5

Related Questions