Erlang消息在进程之间传递

时间:2016-01-24 18:05:13

标签: erlang erlang-shell

我正在编写读取两个输入文件的代码,并检查第一个文件中的单词是否存在于第二个文件中。我想通过流程消息传递逐个检查列表中的元素。

这是我的代码:

[Day [dayNr=22, dayName=vendredi, sumOfHours=PT5M, hours=[Hour [hourNr=10, sumOfEntries=PT5M, entries=[TimeEntry [start=2016-01-22T10:00, duration=PT5M]]]]], Day [dayNr=23, dayName=samedi, sumOfHours=PT10M, hours=[Hour [hourNr=8, sumOfEntries=PT10M, entries=[TimeEntry [start=2016-01-23T08:00, duration=PT7M], TimeEntry [start=2016-01-23T08:43, duration=PT3M]]]]]]

问题在于,当我想发送列表的元素时,它只发送第一个元素。如何修改我的代码以发送所有字符串并检查它们?

1 个答案:

答案 0 :(得分:1)

主要问题是您的check2/0函数只接收一个元素然后退出。它需要循环以接收所有元素,并且还需要一些东西告诉它何时停止。让我们从start/0开始逐个更改函数:

start()->
    Pid2 = spawn(?MODULE,check2,[]),
    check1(Pid2).

此处的更改是不需要生成check2/1 - 它可以直接由start/0运行。

接下来,我们修改了check1/1函数:

check1(Pid2) ->
    {ok, Data} = file:read_file("input.txt"),
    B = binary:split(Data, [<<" ">>,<<"\n">>], [global,trim_all]),
    K = [binary_to_list(Item) || Item <- B],
    [Pid2 ! Element || Element <- K++[stop]].

首先,我们为拆分模式添加了换行符,并且还添加了trim_all选项以从拆分中删除空元素。我们还将原子stop附加到我们发送给Pid2的元素列表中。让我们看看修改后的check2/0函数,看看原因:

check2() ->
    {ok,IoDevice} = file:open("check.txt", [read]),
    L = string:tokens(io:get_line(IoDevice,""), "! .\n"),
    check2(L).

请注意,我们已将原始check2/0拆分为两个功能:check2/0check2/1。这是因为check2/1函数必须是递归的,因此它可以接收发送给它的所有元素:

check2(L) ->
    receive
        stop ->
            ok;
        Element ->
            case lists:member(Element,L)of
                true ->
                    io:format("found: ~s\n", [Element]);
                false ->
                    io:format("not found: ~s\n", [Element])
            end,
            check2(L)
    end.

请注意,在receive内我们首先检查我们是否已收到原子stop,如果我们这样做,我们会退出该功能。否则,我们会收到并检查Element,然后递归调用check2/1,以便它可以接收下一个Elementstop原子。