Reputation: 117
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:
First, I need that the terminate message should correspond to the same form as store and take. Which means the message should be {from, terminate}
and the receiver reply with the message {self(), terminated}
.
Second, I want to respond the sender an unorganized message {From, Msg}
with the message {self(), {not_recognized, Msg}}
.
Third, to add an inventory message {From, {inventory} }
will return to sender (From) the current FoodList
in the fridge2 process.
Fourth, to add a peek message {From, {peek, a} }
will look in the items stored in the process. If a is present, send the message back to the sender (From): {present, a}
. If a is
not present, send the message back to the sender (From): {not_present, a}
.
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:
How could I create a fridge process? Or it's already there?
How could I create a cook process, passing it the fridge process pid?
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
Reputation: 131
Answering your questions:
- 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
- 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.
- 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