-
13-09-2019 - |
質問
私はアーランに非常に新しいだと私は現在、ジョー・アームストロングの本、章「並列プログラミング」を読んでいます。私は数が素数(ナイーブ法)であれば計算するプロセスのリストを実行しようとしています。何のプロセスがなかったかのようにしかし、私のコードが実行されます。どちらの方法でも、同じ持続時間を有します。どこが間違っているのですか?
shell.erlます:
c(prime).
%a list of primes
NUMS=[102950143,102950143,102950143,102950143,102950143].
%time start
NOW1=now().
io:fwrite("Monothread~n").
%for each number test if it is a prime
lists:foreach( fun(N)->
RESULT=prime:is_prime(N),
io:fwrite("Result N=~p ~n",[RESULT])
end, NUMS).
%display the duration
io:fwrite("Duration N=~p ~n",[timer:now_diff(now(),NOW1)/1.0e6]).
%time start
NOW2=now().
io:fwrite("Multithread~n").
%for each number, spawn a new process and test if it is a prime
lists:foreach( fun(N)->ProcId = prime:start(),
io:fwrite("Calculating : procId=~p N=~p ~n",[ProcId,N]),
RESULT=prime:is_prime(ProcId,N),
io:fwrite("Result N=~p ~n",[RESULT])
end, NUMS).
%display the duration
io:fwrite("Duration N=~p ~n",[timer:now_diff(now(),NOW2)/1.0e6]).
halt().
ファイルprime.erlます:
-module(prime).
-export([start/0,is_prime/1,is_prime/2]).
%run the forever_function
start()->spawn(fun forever_function/0).
%catch the queries
forever_function()->
receive
{ From,Number} -> From! is_prime(self(),2,Number),
forever_function()
end.
%monothreaded function
is_prime(Number)->is_prime(self(),2,Number).
%multithreaded function
is_prime(ProcessID,Number)->
ProcessID ! {self(),Number},
receive
RESULT->RESULT
end.
%recursive function scanning all the numbers from 2 to Number
is_prime(ProcessID,Div,Number)->
if
Div =:= Number -> {{number,Number},{prime,true}};
Number rem Div =:= 0 -> {{number,Number},{prime,false}};
true-> is_prime(ProcessID,Div+1,Number)
end.
おかげで、
ピエール
解決
あなたのリストに:第二のブロックでforeachの呼び出し、あなたは結果をRESULT=prime:is_prime(ProcId,N)
をやっているreceive
を呼んでいます。だから、あなたは、プロセスを生成し、それが終了するのをあなたは次のプロセスを起動するまで待っています。それはシングルスレッドアプローチと同じ時間がかかる理由です:両方の方法は、あなたは、一度に1つをやっている。
その代わり、あなたは(すべてのPIDを追跡するためにlists:map
のようなものを使用して)最初に、すべてのプロセスを起動して、別のステップで結果を待つ必要があります。それ以外の場合はあなただけのアイドル状態のプロセスの束を生み出している、あなたはそれが最初のステップで行うことができるようProcessID ! {self(),Number}
部からreceive
の一部を分割する必要があります意味注意ます。
だから、何かます:
Pids = lists:map( fun(N)-> ProcId = prime:start(N),
io:fwrite("Calculating : procId=~p N=~p ~n",[ProcId,N]),
ProcId end, NUMS).
lists:foreach( fun(ProcId) -> {N,RESULT}=prime:is_prime(ProcId),
io:fwrite("Result procId=~p N=~p Result=~p ~n", [ProcId,N,RESULT]) end, Pids).
start(N)->spawn(?MODULE, forever_function, [N]).
forever_function(Number)->
Result = is_prime(self(),2,Number),
receive
{ From, get_result } -> From! {Number,Result},
% unnecessary since we never call this Pid again, but do it anyway :)
forever_function()
% could also add more cases here to set the number
% or even do a one-shot function like before
end.
%multithreaded function
is_prime(ProcessID)->
ProcessID ! {self(),get_result},
receive
RESULT->RESULT
end.
注:これはテストされていないので、それはいくつかの調整が必要な場合があります。
所属していません StackOverflow