1

我还是编程新手和全新的 erlang(2 周新手!)。我稍微编辑了一下,所以至少它会编译和运行。但我仍然无法弄清楚将结果发送到“加入进程”以加入所有单独结果的概念。

它确实拆分并发送接收到的“块”以计算块。只是不知道如何让所有这些过程加入他们各自的结果。我有点理解下面的概念,但不知道这是如何实现的。我已经尝试了很多天和几个小时来达到这一点,但是如果没有得到错误或未绑定的变量等,就无法让它做任何事情。

-module (ccharcount1d).
-compile(export_all).

load(F)->
 {ok, Bin} = file:read_file(F),
  List=binary_to_list(Bin),
  Ls=string:to_lower(List),
  Length=round(length(List)/20),
  Collect_Results = spawn(ccharcount1d, collect_results, []),

  Sl=split(Ls,Length),

  io:fwrite("Loaded, Split, and sent to multiple processes~n").




%%splits txt file into "chunks" and sends those "chunks" to be processed 
split([],_)->[];
split(List,Length)->
S1=string:substr(List,1,Length),
case length(List) > Length of
   true->S2=string:substr(List,Length+1,length(List)),
   Process_Split = spawn(ccharcount1d,receive_splits,[]),
   Process_Split ! {self(), S1};

   false->S2=[],
   Process_Split = spawn(ccharcount1d,receive_splits,[]),
   Process_Split ! {self(), S1}   

 end,  

[S1]++split(S2,Length).


%%recieves the split "chunks" and counts the results 
receive_splits()-> 
    receive
        {From, S1} -> 
            Result=go(S1)
            %Collect_Results ! Result
    end.



collect_results()-> 
    receive
        {Process_Split, Result} ->
            Result=join([],Result)
    end.



join([],[])->[];
join([],R)->R;
join([H1 |T1],[H2|T2])->
{C,N}=H1,
{C1,N1}=H2,
[{C1,N+N1}]++join(T1,T2).



count(Ch, [],N)->N;
count(Ch, [H|T],N) ->
   case Ch==H of
   true-> count(Ch,T,N+1);
   false -> count(Ch,T,N)
end.

go(L)->
Alph=[$a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u,$v,$w,$x,$y,$z],
rgo(Alph,L,[]).

rgo([H|T],L,Result)->
N=count(H,L,0),
Result2=Result++[{[H],N}],
rgo(T,L,Result2);


rgo([],L,Result)-> Result.
4

2 回答 2

3

再说一次,我是新人。我正在理解这个概念。我不理解语法。如何“将 Pid 传递给工作进程”

start() ->
    Work = ...,
    JoinPid = spawn(fun() -> join_func([]) end),  
    WorkerPid = spawn(fun() -> worker_func(JoinPid, Work) end),  %Pass JoinPid to worker process.
    ...

join_func(Acc) ->
    receive
        Result ->
            join_func([Result|Acc]);  %Recursive function call--the life blood of all functional languages.

        ...
    end

worker_func(JoinPid, Work) ->
    Result = ... Work ...,
    JoinPid ! Result.  %Worker process uses JoinPid to send back the results.

另外,看看这个:

8> [$a, $b, $c].
"abc"

9> "abc".
"abc"

输出显示[$a, $b, $c]相当于"abc"。这意味着你可以这样写:

[$a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u,$v,$w,$x,$y,$z]

更简洁如下:

"abcdefghijklmnopqrstuvwxyz"

更重要的是,像这样:

11> lists:seq(97, 122).
"abcdefghijklmnopqrstuvwxyz"
于 2017-04-03T00:17:04.300 回答
2

您需要同步 go 函数的输出。不要在 go 中生成函数,因为我看到所有结果都将进入不同的进程(receive_results)。

最好的解决方案是只在加载函数中生成一个用于加入结果的进程(该进程将 self() 作为输入,以便它可以将最终结果发送回加载函数)。然后将该加入进程引用(J_PID)传递给所有工作进程,这将将结果发送回加入过程。加入过程是一种接收结果的循环。处理完所有块时循环终止。添加一个子句终止加入过程。终止时,加入过程将返回结果给加载函数。

须藤代码:

J_PID = spawn join(self())
spilt(J_PID,....)
wait_for_result(receive Result -> R)

于 2017-04-02T14:30:45.990 回答