Erlang消息传递过程之间 [英] Erlang Message passing between process

查看:344
本文介绍了Erlang消息传递过程之间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这是我的代码:

 开始() - > 
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)||项目< - B],
[Pid2!元素||元素< - K]。

check2() - >
{ok,IoDevice} = file:open(check.txt,[read]),
L = string:tokens(io:get_line(IoDevice,),! ,
收到
元素 - >
案例列表:
的成员(元素,L)true - >
io:format(Element);
false - >
io:format(not_ok)
end
end。

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

解决方案

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

 开始() - > 
Pid2 = spawn(?MODULE,check2,[]),
check1(Pid2)。

这里的更改是,不需要生成 check2 / 1 —它可以直接由 start / 0 直接运行。



接下来,这里是我们修订的 check1 / 1 function:

  check1(Pid2) - > 
{ok,Data} = file:read_file(input.txt),
B = binary:split(Data,[<>,< \\\
>>],[global,trim_all]),
K = [binary_to_list(Item)||项目< - B],
[Pid2!元素||元素< - 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 / 0 check2 / 1 。这是因为 check2 / 1 函数必须递归,因此它可以接收发送给它的所有元素:

  check2(L) - > 
收到
停止 - >
ok;
元素 - >
案例列表:
的成员(元素,L)true - >
io:format(found:〜s\\\
,[Element]);
false - >
io:format(not found:〜s\\\
,[Element])
end,
check2(L)
end。请注意,在收到之前,我们首先检查看看我们是否收到了原子 stop ,如果我们这样做,我们退出该函数。否则,我们收到并检查一个元素,然后递归调用 check2 / 1 ,以便它可以接收下一个元素停止原子。


I am writing code that reads two input files and checks if the words in the first file are present in the second file. I want to check elements of the list one by one via process message passing.

Here is my code:

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.

The problem is that when I want to send an element of the list, it sends just the first element. How can I modify my code to send all strings and check them?

解决方案

The primary issue is that your check2/0 function only receives a single element and then exits. It needs to loop to receive all elements, and it also needs something to tell it when to stop. Let's change the functions one by one below, starting with start/0:

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

The change here is that there's no need to spawn check2/1 — it can just be run directly by start/0.

Next, here's our revised check1/1 function:

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]].

First, we added newline to the split pattern, and also the trim_all option to get rid of empty elements from the split. We also appended the atom stop to the list of elements we send to Pid2. Let's look at our revised check2/0 function to see why:

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

Note that we've split the original check2/0 into two functions: check2/0 and check2/1. This is because the check2/1 function has to be recursive so it can receive all the elements sent to it:

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.

Notice that inside the receive we first check to see if we've received the atom stop, and if we do, we exit the function. Otherwise, we receive and check an Element, and after that call check2/1 recursively so it can receive either the next Element or the stop atom.

这篇关于Erlang消息传递过程之间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆