لماذا لا يعمل رمز Erlang هذا؟
-
18-09-2019 - |
سؤال
fib(N)->
P1 = spawn(fun concFib:conFib/0),
P2 = spawn(fun concFib:conFib/0),
X=rpc(P1,N-2),Y=rpc(P2,N-1),X+Y.
conFib()->
receive
{Client,N} -> Client ! regfib(N)
end.
rpc(Pid,Request)->
case erlang:is_process_alive(Pid) of
true -> begin
Pid ! {self(),Request},
receive
{Pid,Respond} -> Respond
end
end;
false -> io:format("~w process is dead.",[Pid])
end.
regfib(N)->
case N<2 of
true -> 1;
false -> regfib(N,1,1,1)
end.
regfib(N,N,X,_)-> X ;
regfib(N,M,X,Y)-> regfib(N,M+1,X+Y,X).
هذه الفكرة هي تقسيم عملية FIB (N) إلى عنصرين يقوم بتحديد FIB (N-2) والآخر Calc. FIB (N-1) بشكل متزامن كما fib (n) = fib (n-1) + fib (n-2). عندما أقوم بتشغيل الرمز السابق، يحدث شيء ووقف المؤشر كما في حلقة محددة أو انتظار عدم الوصول إلى النتيجة.
plzzz أحتاج إلى مساعدة أنا مبرمج Erlang جديد، شكرا مقدما :)
المحلول
في Confib، يمكنك إرسال عدد صحيح، ولكن في انتظار Tuple في RPC. يجب تغييره إلى:
conFib()->
receive
{Client,N} -> Client ! {self(), regfib(N)}
end.
يمكنك تجنب مثل هذه المواقف باستخدام المهلة مع after
في تلقي الخاص بك.
نصائح أخرى
لجعل الحساب متوازيا يمكنك فعل شيء مثل:
fib(N)->
P1 = spawn(fun test:conFib/0),
P2 = spawn(fun test:conFib/0),
P1 ! {self(), N - 2},
P2 ! {self(), N - 1},
receive
{_, R1} -> R1
end,
receive
{_, R2} -> R2
end,
R1 + R2.
الجزء المهم هو أنك ترسل كل من الطلبات قبل انتظار الإجابات. الجزء الذي ينتظر الإجابات قد تتم بالطبع بطريقة أكثر جمالا.
لا تنتمي إلى StackOverflow