2012-10-02 61 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

谢谢,这似乎是。其他进程确实是将消息发送给未注册的名称。 –