如何在 Erlang 中对多个值使用发送接收?

Posted

技术标签:

【中文标题】如何在 Erlang 中对多个值使用发送接收?【英文标题】:How can I use send receive for multiple values in Erlang? 【发布时间】:2021-02-22 02:54:05 【问题描述】:

我有以下循环:

for( i = 1 ; i < V ; i++ )

    i sends "hi" to arr[i]


for( i = 1 ; i <arr.size ; i++ )

    if arr[i] receives "hi"
    
        print "bye"
    


如何在 erlang 中实现这些代码?

我了解简单的乒乓球,但我想并行创建这段代码,以平衡负载。我对循环实现部分有些困惑。

【问题讨论】:

你必须使用递归或高阶函数。我可以为您编写代码,但这可能对您没有好处。我建议你先检查这里:learnyousomeerlang.com/recursion 感谢您的评论。我需要创建节点还是简单的发送接收代码可以工作?循环通过递归非常容易,是的。但它不会产生某种顺序行为吗? 我应该使用 spawn 吗? 是的,根据您想要实现的并发性,您可能需要在递归或高阶函数中生成进程,并且这些进程需要接收语句。创建节点可能有点太多了,但话说回来……我不知道你练习的具体要求。 Spawn 应该可以工作,我想要一个比顺序更快的代码,是的,节点可能有点太多了。再次,非常感谢! 【参考方案1】:

以下是您可以执行的操作的示例:

-module(a).
-compile(export_all).

worker() ->
    receive
        hi, From ->
            From ! bye, self(),
            worker();
        stop ->
            io:format("Worker ~w terminated.~n", [self()]);
        _Other ->
            io:format("Bad message received by worker: ~w~n", [self()]),
            worker()
    end.


create_workers(N) ->
    create_workers(N, _Pids=[]).

create_workers(0, Pids) -> Pids;
create_workers(N, Pids) ->
    Pid = spawn(a, worker, []),
    create_workers(N-1, [Pid|Pids]).

test()->
    N = 4,
    Workers = create_workers(N),
    RandNum1 = rand:uniform(N),
    RandNum2 = rand:uniform(N),
    Worker1 = lists:nth(RandNum1, Workers),
    Worker2 = lists:nth(RandNum2, Workers),

    Worker1 ! hello,
    Worker1 ! hi, self(),

    Worker2 ! xxxx, self(),
    Worker2 ! hi, self(),

    Results = get_results(2, _Acc=[]),
    io:format("Worker results: ~w~n", [Results]),
    terminate(Workers).


get_results(0, Acc) -> Acc;
get_results(N, Acc) ->
    Result = receive
                 Msg, _From -> Msg
             end,
    get_results(N-1, [Result|Acc]).

terminate(Workers) ->
    lists:foreach(fun(Worker) -> Worker ! stop end,
            Workers).

在外壳中:

6> c(a).    
a.erl:2: Warning: export_all flag enabled - all functions will be exported
ok,a

7> a:test().
Worker results: [bye,bye]
Bad message received by worker: <0.96.0>
Bad message received by worker: <0.99.0>
Worker <0.96.0> terminated.
Worker <0.99.0> terminated.
Worker <0.98.0> terminated.
Worker <0.97.0> terminated.
ok

【讨论】:

以上是关于如何在 Erlang 中对多个值使用发送接收?的主要内容,如果未能解决你的问题,请参考以下文章

Erlang消息发送和接收与多个进程

如何在 erlang gen_server 中有效地使用接收子句来解决超时错误?

将erlang记录发送到c程序

为啥第二次调用接收没有在 Erlang shell 中检索消息?

如何在erl中为单个标志设置多个命令行参数

在一个变量 sql 中接收多个值