Erlang 多处理消息接收和发送
Erlang multiprocessing messages receiving and sending
我正在学习 "Learn you some Erlang" 这本书。我有几个关于使用 Erlang 进行多处理编程的问题要解决。基本上就是边读边模仿"Learn you some Erlang"。我在我的程序中生成了一个带有一些面向功能的程序。它说冰箱可以像自己一样存放和取用。因此,我正在处理我的程序以在遵循以下基础的基础上进行一些操作:
首先,我需要终止消息应该对应于与存储和获取相同的形式。这意味着消息应该是 {from, terminate}
并且接收者回复消息 {self(), terminated}
.
其次,我想用消息 {self(), {not_recognized, Msg}}
.
回复发件人一条未组织的消息 {From, Msg}
三、添加库存消息{From, {inventory} }
将return发送给fridge2进程中的当前FoodList
return。
第四,添加一个peek message {From, {peek, a} }
将查看进程中存储的项目。如果存在 a,则将消息发送回发件人(发件人):{present, a}
。如果一个是
不存在,将消息发回给发件人(发件人):{not_present, a}
.
我对冰箱本身的用法一头雾水。我用教程中的示例代码想出了类似下面的内容:
-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]).
除此之外,还有一些我一直在思考的问题:
如何创建冰箱进程?或者它已经存在了?
如何创建一个 cook 进程,将其传递给冰箱进程 pid?
我怎么能把东西放在冰箱里然后睡几秒钟,最后我可以从冰箱里拿出东西?
这可能不是最复杂的问题,但我找不到任何关于此的文档,所以我很感激你们中的一些人可能知道答案。
回答您的问题:
- How could I create a fridge process? Or it's already there?
一旦您从 erlang shell 或另一个模块调用 kitchen:start/1
,函数 spawn(?MODULE, fridge2, [FoodList])
将为您生成一个进程。查看文档以获取更多详细信息:http://www.erlang.org/doc/man/erlang.html#spawn-3
- How could I create a cook process, passing it the fridge process pid?
正如我在第一个答案中所说,spawn/3
以 module
、function
和 arguments
作为参数,是您可以使用的功能之一用于生成新进程。因此,您应该使用它来生成一个接收 kitchen:fridge2/1
pid 作为参数的进程,例如
Kitchen = kitchen:start([]),
Cook = spawn(cook_module, cook_function, [Kitchen]).
这样你将产生一个执行 cook_module:cook_function/1
并传递 Kitchen
(fridge 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?
您可以使用 store/2
函数将物品存储到冰箱,稍等片刻(或几秒钟,如您所愿),然后使用 take/2
函数从冰箱中取出东西.就像这样:
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));
我正在学习 "Learn you some Erlang" 这本书。我有几个关于使用 Erlang 进行多处理编程的问题要解决。基本上就是边读边模仿"Learn you some Erlang"。我在我的程序中生成了一个带有一些面向功能的程序。它说冰箱可以像自己一样存放和取用。因此,我正在处理我的程序以在遵循以下基础的基础上进行一些操作:
首先,我需要终止消息应该对应于与存储和获取相同的形式。这意味着消息应该是
{from, terminate}
并且接收者回复消息{self(), terminated}
.其次,我想用消息
{self(), {not_recognized, Msg}}
. 回复发件人一条未组织的消息 三、添加库存消息
{From, {inventory} }
将return发送给fridge2进程中的当前FoodList
return。第四,添加一个peek message
{From, {peek, a} }
将查看进程中存储的项目。如果存在 a,则将消息发送回发件人(发件人):{present, a}
。如果一个是 不存在,将消息发回给发件人(发件人):{not_present, a}
.
{From, Msg}
我对冰箱本身的用法一头雾水。我用教程中的示例代码想出了类似下面的内容:
-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]).
除此之外,还有一些我一直在思考的问题:
如何创建冰箱进程?或者它已经存在了?
如何创建一个 cook 进程,将其传递给冰箱进程 pid?
我怎么能把东西放在冰箱里然后睡几秒钟,最后我可以从冰箱里拿出东西?
这可能不是最复杂的问题,但我找不到任何关于此的文档,所以我很感激你们中的一些人可能知道答案。
回答您的问题:
- How could I create a fridge process? Or it's already there?
一旦您从 erlang shell 或另一个模块调用 kitchen:start/1
,函数 spawn(?MODULE, fridge2, [FoodList])
将为您生成一个进程。查看文档以获取更多详细信息:http://www.erlang.org/doc/man/erlang.html#spawn-3
- How could I create a cook process, passing it the fridge process pid?
正如我在第一个答案中所说,spawn/3
以 module
、function
和 arguments
作为参数,是您可以使用的功能之一用于生成新进程。因此,您应该使用它来生成一个接收 kitchen:fridge2/1
pid 作为参数的进程,例如
Kitchen = kitchen:start([]),
Cook = spawn(cook_module, cook_function, [Kitchen]).
这样你将产生一个执行 cook_module:cook_function/1
并传递 Kitchen
(fridge 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?
您可以使用 store/2
函数将物品存储到冰箱,稍等片刻(或几秒钟,如您所愿),然后使用 take/2
函数从冰箱中取出东西.就像这样:
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));