2017-04-02 73 views
2

我還是新編程和全新erlang(2周新手!)。我編輯稍微,至少它會編譯和運行。但我仍然無法弄清楚將結果發送到「加工程序」以加入所有單獨結果的概念。Erlang新手 - 併發和消息傳遞

它分裂併發送接收到的「塊」來計算塊。只是不知道如何讓所有這些過程加入他們的個人成果。我有點理解下面的概念,但不知道這是如何實現的。我一直在嘗試了很多天時間,對得到它了這一點,但不能讓它沒有得到錯誤或綁定變量做任何事情,等

-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. 
+0

*我還是新的編程和全新的erlang(2周新手!)*在我看來,糟糕的主意。學習python。花一年的時間玩它,然後決定你想從那裏去哪裏。 – 7stud

回答

4

再次,我新的。我正在理解這個概念。我不理解 的語法。該如何 「通過一個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]相當於​​。這意味着你可以這樣寫:

[$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" 
3

你需要去的同步輸出功能。 不要在函數內部產生函數,因爲我看到所有結果都進入不同的過程(receive_results)。

最佳的解決方案是一個產卵過程只加載函數內部接合結果(這個過程需要自我()作爲輸入,以便它可以發送最終結果返回給加載功能)。然後它傳遞給所有參與的過程引用(J_PID)工作進程將返回結果加入進程。加入進程是receive_results類型的循環。當所有的chunks被處理時,loop終止。添加一個子句來終止join過程。在結束時,join過程會把結果發送回加載函數。

須藤代碼:

J_PID =產卵加入(個體())
溢出(J_PID,....)
wait_for_result(接收結果 - > R)

+0

好的,不好意思,但是我在編程和Erlang中只有2周的時間,Theres很瞭解你說的我需要分解才能理解。我需要做的是如果我的理解正確,我需要刪除它: DELETE'rgo([],L,Result) - >' DELTETE'Process_Results = spawn(ccharcount1d,receive_results,[]) ,' DELETE'Process_Results! {self(),Result} .' 簡單地放在'rgo([],L,Result) - > Result.' – chitown88

+0

然後在加載函數中,'io:format(「Load,split ... ...),'我可以派生加入過程。 – chitown88

+0

你有點迷失了我。我明白你的意思是說結果會落在不同的過程中。但我不完全理解「通過加入進程到工作進程部分」 – chitown88