【问题标题】:How can I implement the following loop in Erlang?如何在 Erlang 中实现以下循环?
【发布时间】:2021-02-19 22:05:02
【问题描述】:

我有以下伪代码:

for ( int i = 0; i < V ; i++ )
{
  for( int j = 0 ; j < V ; j++ )
  {
    if( ( i != j ) && ( tuple {i,j} belong to E ) )
    {
      R[i] := {i,j};
    }
  }
}

我想使用 并行化这段代码。
如何使用 Erlang 实现相同的目标? 我是 Erlang 新手...

编辑:

我知道以下代码同时运行对say/2 的调用:

-module(pmap).

-export([say/2]).

say(_,0) ->
  io:format("Done ~n");

say(Value,Times) ->
  io:format("Hello ~n"),
  say(Value,Times-1).

start_concurrency(Value1, Value2) ->
  spawn(pmap, say, [Value1, 3]),
  spawn(pmap, say, [Value2, 3]).

但是,我们在这里对函数进行硬编码。那么,假设我想调用say 1000 次,我需要写spawn(pmap, say, [Valuex, 3]) 1000 次吗?我可以使用递归,但它不会提供顺序性能吗?

编辑:

我尝试了以下代码,我的目标是创建 3 个线程,每个线程都想运行一个 say 函数。我想同时运行这 3 个 say 函数(请在框中评论以获得更多说明):

-module(pmap).

-export([say/1,test/1,start_concurrency/1]).

say(0) ->
  io:format("Done ~n");

say(Times) ->
  io:format("Hello ~p ~n",[Times]),
  say(Times-1).

test(0) ->
  spawn(pmap, say, [3]);

test(Times) ->
  spawn(pmap, say, [3]),
  test(Times-1).

start_concurrency(Times) ->
  test(Times).

这段代码正确吗?

【问题讨论】:

    标签: erlang parallel-processing erlang distributed-computing distributed-system erlang-otp


    【解决方案1】:

    我想同时运行这 3 个 say 函数。这是代码吗 对吗?

    你可以去掉你的start_concurrency(N) 函数,因为它什么都不做。相反,您可以直接致电test(N)

    我的目标是创建 3 个线程

    在 erlang 中,您创建 processes

    在 erlang 中,缩进是 4 个空格,而不是 2 个。

    不要在函数定义的多个函数子句之间放置空行。

    如果您想看到并发运行,那么您正在并发运行的任务中必须有一些等待。例如:

    -module(a).
    -compile(export_all).
    
    say(0) ->
        io:format("Process ~p finished.~n", [self()]);
    say(Times) ->
        timer:sleep(rand:uniform(1000)),  %%perhaps waiting to receive data from an http request
        io:format("Hello ~p from process ~p~n",[Times, self()]),
        say(Times-1).
    
    loop(0) ->
        spawn(a, say, [3]);
    loop(Times) ->
        spawn(a, say, [3]),
        loop(Times-1).
    

    在外壳中:

    3> c(a).     
    a.erl:2: Warning: export_all flag enabled - all functions will be exported
    {ok,a}
    
    4> a:loop(3).
    <0.84.0>
    Hello 3 from process <0.82.0>
    Hello 3 from process <0.81.0>
    Hello 2 from process <0.82.0>
    Hello 3 from process <0.83.0>
    Hello 2 from process <0.81.0>
    Hello 3 from process <0.84.0>
    Hello 2 from process <0.83.0>
    Hello 1 from process <0.81.0>
    Process <0.81.0> finished.
    Hello 1 from process <0.82.0>
    Process <0.82.0> finished.
    Hello 2 from process <0.84.0>
    Hello 1 from process <0.83.0>
    Process <0.83.0> finished.
    Hello 1 from process <0.84.0>
    Process <0.84.0> finished.
    
    5>
    

    如果您正在并发运行的任务中没有随机等待,那么这些任务将按顺序完成:

    -module(a).
    -compile(export_all).
    
    say(0) ->
        io:format("Process ~p finished.~n", [self()]);
    say(Times) ->
        %%timer:sleep(rand:uniform(1000)),
        io:format("Hello ~p from process ~p~n",[Times, self()]),
        say(Times-1).
    
    loop(0) ->
        spawn(a, say, [3]);
    loop(Times) ->
        spawn(a, say, [3]),
        loop(Times-1).
    

    在外壳中:

    5> c(a).     
    a.erl:2: Warning: export_all flag enabled - all functions will be exported
    {ok,a}
    
    6> a:loop(3).
    Hello 3 from process <0.91.0>
    Hello 3 from process <0.92.0>
    Hello 3 from process <0.93.0>
    Hello 3 from process <0.94.0>
    <0.94.0>
    Hello 2 from process <0.91.0>
    Hello 2 from process <0.92.0>
    Hello 2 from process <0.93.0>
    Hello 2 from process <0.94.0>
    Hello 1 from process <0.91.0>
    Hello 1 from process <0.92.0>
    Hello 1 from process <0.93.0>
    Hello 1 from process <0.94.0>
    Process <0.91.0> finished.
    Process <0.92.0> finished.
    Process <0.93.0> finished.
    Process <0.94.0> finished.
    
    7> 
    

    如果您正在并发运行的任务中没有随机等待,那么并发没有任何好处。

    【讨论】:

    • 非常感谢,通过这个回答我学到了一些非常重要的东西。
    猜你喜欢
    • 2014-06-01
    • 2014-02-15
    • 1970-01-01
    • 2012-04-16
    • 2020-07-12
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多