在Erlang中获取生成函数的结果 [英] Getting result of a spawned function in Erlang
问题描述
在我的代码中,我想使用一个函数作为给定N的循环,N,N-1,N-2 ...产生一个计算阶乘(N)的过程,并发送导致一些收集功能,将接收到的结果打包到列表中。我知道我的概念可能是过于复杂的,所以希望代码会更多解释一下:
messageFactorial(N,listPID) - > ;
listPID!阶乘(N)。 %%将计算的阶乘发送到收藏家。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%
nProcessesFactorialList(-1) - >
ok;
nProcessesFactorialList(N) - >
spawn(pFactorial,messageFactorial,[N,listPID]),每个N个生成的%% ...
nProcessesFactorialList(N-1)。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
listPrepare(List) - > %%collector,对于最后一个阶乘返回
接收%%一个阶乘列表(1!= 1)。
1 - >清单;
X - >
listPrepare([X | List])
end。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %
startProcessesFactorialList(N) - >
register(listPID,spawn(pFactorial,listPrepare,[[]])),
nProcessesFactorialList(N)。
我想这将工作,我的意思是listPrepare终于返回一个阶乘列表。但问题是,我不知道如何得到这个列表,如何得到它返回的?至于现在我的代码返回ok,因为这是nProcessesFactorialList在其完成时返回的。我想到最后将listPrepare的结果列表发送到nProcessesFactorialList,但是它也需要是一个已注册的进程,我不知道如何恢复该列表。
所以基本上,如何从一个注册进程运行listPrepare(这是我的列表)获得结果?如果我的代码根本不对,我会问一个如何更好的建议。感谢提前。
我的方式如何做这种任务是
-module(par_fact)。
-export([calc / 1])。
fact(X) - >事实(X,1)。
fact(0,R) - > R等
事实(X,R)当X> 0 - >事实(X-1,R * X)。
calc(N) - >
Self = self(),
Pids = [spawn_link(fun() - > Self!{self(),{X,fact(X)}} end)
|| X <列表:seq(1,N)],
[receive {Pid,R} - > R end || Pid< - Pids]。
结果:
> par_fact:计算值(25)。
[{1,1},
{2,2},
{3,6},
{4,24},
{5,120},
{6,720},
{7,5040},
{8,40320},
{9,362880},
{10,3628800},
{11,39916800},
{12,479001600},
{13,6227020800},
{14,87178291200},
{15,1307674368000},
{16,20922789888000},
{17,355687428096000},
{18,6402373705728000},
{19,121645100408832000},
{20,2432902008176640000},
{21,51090942171709440000},
{22,1124000727777607680000},
{23,25852016738884976640000},
{24,620448401733239439360000},
{25,15511210043330985984000000}]
My objective at the moment is to write Erlang code calculating a list of N elements, where each element is a factorial of it's "index" (so, for N = 10 I would like to get [1!, 2!, 3!, ..., 10!]). What's more, I would like every element to be calculated in a seperate process (I know it is simply inefficient, but I am expected to implement it and compare its efficiency with other methods later).
In my code, I wanted to use one function as a "loop" over given N, that for N, N-1, N-2... spawns a process which calculates factorial(N) and sends the result to some "collecting" function, which packs received results into a list. I know my concept is probably overcomplicated, so hopefully the code will explain a bit more:
messageFactorial(N, listPID) ->
listPID ! factorial(N). %% send calculated factorial to "collector".
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nProcessesFactorialList(-1) ->
ok;
nProcessesFactorialList(N) ->
spawn(pFactorial, messageFactorial, [N, listPID]), %%for each N spawn...
nProcessesFactorialList(N-1).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
listPrepare(List) -> %% "collector", for the last factorial returns
receive %% a list of factorials (1! = 1).
1 -> List;
X ->
listPrepare([X | List])
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
startProcessesFactorialList(N) ->
register(listPID, spawn(pFactorial, listPrepare, [[]])),
nProcessesFactorialList(N).
I guess it shall work, by which I mean that listPrepare finally returns a list of factorials. But the problem is, I do not know how to get that list, how to get what it returned? As for now my code returns ok, as this is what nProcessesFactorialList returns at its finish. I thought about sending the List of results from listPrepare to nProcessesFactorialList in the end, but then it would also need to be a registered process, from which I wouldn't know how to recover that list.
So basically, how to get the result from a registered process running listPrepare (which is my list of factorials)? If my code is not right at all, I would ask for a suggestion of how to get it better. Thanks in advance.
My way how to do this sort of tasks is
-module(par_fact).
-export([calc/1]).
fact(X) -> fact(X, 1).
fact(0, R) -> R;
fact(X, R) when X > 0 -> fact(X-1, R*X).
calc(N) ->
Self = self(),
Pids = [ spawn_link(fun() -> Self ! {self(), {X, fact(X)}} end)
|| X <- lists:seq(1, N) ],
[ receive {Pid, R} -> R end || Pid <- Pids ].
and result:
> par_fact:calc(25).
[{1,1},
{2,2},
{3,6},
{4,24},
{5,120},
{6,720},
{7,5040},
{8,40320},
{9,362880},
{10,3628800},
{11,39916800},
{12,479001600},
{13,6227020800},
{14,87178291200},
{15,1307674368000},
{16,20922789888000},
{17,355687428096000},
{18,6402373705728000},
{19,121645100408832000},
{20,2432902008176640000},
{21,51090942171709440000},
{22,1124000727777607680000},
{23,25852016738884976640000},
{24,620448401733239439360000},
{25,15511210043330985984000000}]
这篇关于在Erlang中获取生成函数的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!