gpt4 book ai didi

multithreading - Erlang 和进程

转载 作者:行者123 更新时间:2023-12-03 13:14:10 24 4
gpt4 key购买 nike

我对 Erlang 很陌生,目前正在阅读 Joe Armstrong 的书,“并发编程”一章。我正在尝试运行一个进程列表来计算一个数字是否是素数(天真的方法)。但是我的代码就像没有进程一样运行。两种方法的持续时间相同。我哪里错了?

外壳.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 在第二个 block 中调用,您正在调用 RESULT=prime:is_prime(ProcId,N) ,这是在做 receive为结果。因此,您正在生成一个进程,然后等待它完成,直到生成下一个进程。这就是为什么它需要与单线程方法相同的时间:两种方式,你一次只做一个。

相反,您需要先生成所有进程(使用 lists:map 之类的东西来跟踪所有 PID),然后在单独的步骤中等待结果。请注意,这意味着您必须拆分 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.

注意:这是未经测试的,因此可能需要一些调整。

关于multithreading - Erlang 和进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1855480/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com