2013-01-23 41 views
0

我是新来的Erlang,我需要产生两个进程运行加入函数,然后加上两个数字 。 过程一和二的赋值分别显示进程ID,我需要捕获这个值。如何在我的calc函数中读取add(N)函数的返回值?

如何在我的calc函数中读取add(N)函数的返回值?

-module(myerl). 
-export([calc/1,add/1]). 

add(N) -> 
    N + 5. 


calc(L) 

pone = spawn(fun() -> add(A) end), 
ptwo = spawn(fun() -> add(B) end), 

Result = Pone + Ptwo, 
io:format("result ~p~n", [Result]). 

回答

3

您需要使用消息传递。您必须将结果发送回调用进程。 spawn函数将PID(进程标识符)返回给新产生的进程,而不是执行结果。

这个例子应该做你期待什么:

calc(A, B) -> 
    Self = self(),  % The spawned funs need a Pid to send to, use a closure 
    POne = spawn(fun() -> Self ! {self(), add(A)} end), 
    PTwo = spawn(fun() -> Self ! {self(), add(B)} end), 
    wait_for_response(POne, PTwo, 0). 

wait_for_response(undefined, undefined, Sum) -> 
    Sum; 
wait_for_response(POne, PTwo, Sum) -> 
    receive 
     {POne, V} -> wait_for_response(undefined, PTwo, Sum + V); 
     {PTwo, V} -> wait_for_response(POne, undefined, Sum + V) 
    end. 
+0

非常感谢,非常感谢。 – Shaka

+0

@Shaka如果你在这里找到了解决方案,你应该接受一个答案 –

2

@Soup D'坎贝尔的解释还是不错的。我本能地做了一些稍微不同的事情,用玩具的方式预测孩子进程会有一些不好的行为。另外,我允许输入的是数字列表,不仅仅是2.

-module(myerl). 
-export([calc/1, add/1]). 

calc(NumList) when is_list(NumList)-> 
    Parent = self(), 
    _Pids = [spawn(fun()-> Parent ! add(ANum) end) || ANum <- NumList], 
    collect(length(NumList), 0); 
calc(_) -> 
    {error, badarg}. 

collect(0, Sum) -> 
    Sum; 
collect(Cnt, Sum) -> 
    receive 
     N when is_number(N) -> 
      collect(Cnt-1, Sum + N); 
     _Bad -> % returned something that isnt a number 
      collect(Cnt-1, Sum) 
    after 1000 -> % died or is too slow 
     collect(Cnt-1, Sum) 
    end. 

add(N) -> 
    N + 5. 
+0

我为了简单起见,但指出彻底。尽管我必须指出,如果你真的希望预测不良行为,你应该使用'spawn_monitor'或甚至'Parent! catch add(ANum)' –

+0

好点,你说得对。 – Jr0

+0

感谢Jro的回答。你能解释一下这条线吗?我没有得到这部分**粗体**,'|| ANum < - NumList]', – Shaka