在Erlang中获取生成函数的结果 [英] Getting result of a spawned function in Erlang

查看:137
本文介绍了在Erlang中获取生成函数的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前的目标是写Erlang代码来计算N个元素的列表,其中每个元素是它的索引的阶乘(因此,对于N = 10,我想得到[1 !, 2! 3 !, ...,10!])。更重要的是,我希望在一个单独的过程中计算每一个元素(我知道这样做效率很低,但是我预计会实现它,并将其效率与其他方法进行比较)。



在我的代码中,我想使用一个函数作为给定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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆