concurrency - 并发 Prime 生成器

标签 concurrency erlang primes

我正在通过 projecteuler.net 上的问题来学习如何在 Erlang 中编程,而我最难的是创建一个可以在不到一分钟的时间内创建所有低于 200 万的素数的素数生成器。使用顺序样式,我已经编写了三种类型的生成器,包括 Eratosthenes 的筛子,它们都没有表现得足够好。

我认为并发 Sieve 会很好用,但我收到 bad_arity 消息,我不知道为什么。关于我为什么遇到问题或如何正确编码的任何建议?

这是我的代码,注释掉的部分是我试图使事情并发的地方:

-模块(主服务器)。
-编译(export_all)。

开始()->
注册(素数,产卵(乐趣()->循环()结束))。

is_prime(N) -> rpc({is_prime,N})。

RPC(请求)->
素数! {self(), 请求},
收到
{素数,响应} ->
回复
结尾。

循环()->
收到
{来自,{is_prime,N}} ->
如果
N 从! {素数,假};
N =:= 2 -> 从! {素数,真};
N rem 2 =:= 0 -> 从! {素数,假};
真->
值 = is_not_prime(N),
Val = not(lists:member(true, Values)),
从 ! {素数,瓦尔}
结尾,
环形()
结尾。

for(N,N,_,F) -> [F(N)];
for(I,N,S,F) 当 I + S [F(I)|for(I+S, N, S, F)];
for(I,N,S,F) 当 I + S =:= N -> [F(I)|for(I+S, N, S, F)];
当 I + S > N -> [F(I)] 时,for(I,N,S,F)。

get_list(I, 限制) ->
如果
一世
[我*A ||一种
[]
结尾。

is_not_prime(N) ->
对于(3, N, 2,
乐趣(一)->
列表 = get_list(I,trunc(N/I)),
列表:成员(N,列表:展平(列表))
结尾
)。

%%L = for(1,N, fun() -> spawn(fun(I) -> wait(I,N) end) end),
%%SeedList = [A ||一种
%% 列表:foreach(fun(X) ->
%% 密码! {in_list, X}
%% 结束,种子列表)
%% 结束,L)。

%%等待(I,N) ->
%% 列表 = [I*A ||一个列表:成员(X,列表)
%% 结尾。

最佳答案

我使用 Go 和 channels 编写了一个 Eratosthenesque 并发初筛。

这是代码:http://github.com/aht/gosieve

我在这里写了一篇博客:http://blog.onideas.ws/eratosthenes.go

该程序可以在大约 10 秒内筛选出前一百万个素数(所有素数最多为 15,485,863)。筛子是并发的,但算法主要是同步的:goroutines(“actors”——如果你喜欢的话)之间需要太多的同步点,因此它们不能并行自由地漫游。

关于concurrency - 并发 Prime 生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/89705/

相关文章:

java - Java中简单多线程程序的奇怪问题

c# - 停止两个异步方法与另一个方法同时运行

erlang - 配置啤酒 - 我收到此错误 : undefined parse transform 'lager_transform'

testing - 如何正确测试 GenServer 中的 handle_cast?

algorithm - Miller-Rabin Scheme 实现不可预测的输出

javascript - 实现 Lucas–Lehmer 素性检验的问题

java - 在同一类的线程之间共享记录器

python - 如何做一个 "real concurrent"协程

Erlang 与 Elixir 宏

c++ - 质数显示和计数c++