【问题标题】:Erlang Message passing between processErlang 进程间消息传递
【发布时间】:2016-04-30 23:36:03
【问题描述】:

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

这是我的代码:

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

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

check2() ->
    {ok,IoDevice} = file:open("check.txt", [read]),
    L = string:tokens(io:get_line(IoDevice,""), "! ."),
    receive
        Element ->
            case lists:member(Element,L)of
                true ->
                    io:format(Element);
                false ->
                    io:format("not_ok")
            end
    end.

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

【问题讨论】:

  • @Steve Vinoski:我在这个问题上扩展得更好,这是我的代码,我希望你能看到我的错误......

标签: erlang erlang-shell


【解决方案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 原子。

【讨论】:

  • tnx 非常需要您的帮助,我还有另一个问题我正在尝试过滤找到的元素,例如如果找到的元素是此列表的成员 ["amazing","good","great","intresting","wonderful","valuable","super","excellent","admirable","awesome"] 打印 1 否则如果元素是此列表["bad","garbage","terrible","horrible","boring","poor","weak","nok awful", "second-rate] print (-1)...我想在check2/1 中通过混合两个(大小写)语句来实现,但它不起作用...
  • 你需要阅读并传递两个列表,一个是好的条目,一个是坏的。使用lists:member2 来检查一个列表,就像你已经做的那样,但在未找到的情况下,用另一个案例检查另一个列表,同样使用lists:member/2
猜你喜欢
  • 2016-04-30
  • 1970-01-01
  • 2011-03-24
  • 2011-04-03
  • 1970-01-01
  • 1970-01-01
  • 2014-06-07
  • 2012-04-27
  • 2023-03-31
相关资源
最近更新 更多