2012-10-02 58 views
1

我試圖讓Erlang程序找到與進程素數(無效,我知道,但嘿,它只是爲了好玩:)) - 東西沿numbersimulation.com行。Erlang錯誤發送到註冊過程

在每個「tick」上,服務器產生一個增加計數器的新進程(「數字」)。如果計數器==這個數字,這是一個因素,所以我們讓服務器知道。如果服務器沒有收到任何消息,這是一個質數。

在小數字(素數高達N,該server(50,L)線)也沒關係,但在更大的人將其與崩潰:

Error in process <0.46.0> with exit value: {badarg,[{primes,number,2,[{file,"primes.erl"},{line,31}]}]}

線31是server ! hit一個 - 但我不不明白爲什麼失敗。也許是失敗的那一行,number(N,1)但爲什麼會失敗?

代碼:

-module(primes). 
-compile(export_all). 

main() -> 
    pg:create(numbers), 
    Server_PID = spawn(?MODULE,server,[]), 
    register(server,Server_PID), 
    ok. 

server()  -> server(2,[]). 
server(50,L) -> io:format("Primes: ~p~n",[L]); 
server(N,L) -> 
    Num_PID = spawn(?MODULE,number,[N]), 
    pg:join(numbers,Num_PID), 
    pg:send(numbers,tick), 
    receive 
    hit -> 
     flush(), 
     server(N+1,L) 
    after 100 -> 
     server(N+1,[N|L]) 
    end. 

number(N) -> receive {pg_message,_,_,tick} -> number(N,1) end. 
number(N,I) -> 
    receive 
    {pg_message,_,_,tick} -> 
     if 
     N =:= I -> 
      server ! hit, 
      number(N,1); 
     true -> 
      number(N,I+1) 
     end 
    end. 

flush() -> 
    receive _ -> flush() 
    after 0 -> ok end. 

回答

7

如果註冊的過程中去世它是根據不再被登記註冊的名稱。發送消息給指向死程序的pid是完全合法的(消息只是消失),即使該名稱曾經註冊過,發送給未註冊名稱也是一個錯誤。

在您的代碼中,server進程會產生50個循環,產生一個新進程並等待hit消息或超時。之後server/2函數結束,server進程結束。當它死亡時,名稱server不再註冊,因此嘗試向其發送消息時會生成badarg錯誤。

+0

謝謝,這似乎是。其他進程確實是將消息發送給未註冊的名稱。 –