2010-11-18 236 views
2

我正在實現一個聊天服務器Erlang。根據我的設計,每個客戶端在處理消息的服務器節點上都有相應的代理進程。我正在將代理的PIDs寫入數據庫,以便我可以在它們之間交換消息。通過PID在Erlang中殺死進程

當我殺死PIDs是否安全?例如,在我的服務器重新啓動後,PID仍在數據庫中(但進程將會死亡),數據庫中的PID是否會與其他一些(新創建的)重要進程衝突?

如果是這樣,我不能簡單地殺死客戶端沒有響應時的代理。到目前爲止,我還沒有觀察到它,但很確定地知道這一點。

回答

7

每次啓動節點時,PID都會從0.0.0(init)開始以spawn順序分配。所以是的,如果您在節點重新啓動之間保存它們,您可以輕鬆獲得PID衝突。

你已經建立了某種形式的註冊表,讓你查找的PID爲特定的客戶端 - 此註冊表需要去除及時死的PID。一個典型的設計是用於註冊表監視(erlang:monitor/2)每個註冊的進程並刪除註冊表項,當進程死亡並收到{'DOWN', Ref, process, Pid, Info}消息。

我還想補充一點,存儲PID外二郎(如果你的數據庫是不是ETS或者Mnesia的)是不尋常的這個原因 - 進程或節點去世後,PID將沒有任何意義。

0

可以在重新啓動時重新使用PID。它們很可能會與其他PID相沖突,因爲它們是連續的。您應該確保清除數據庫中與已關閉節點相對應的任何PID。

1> spawn(fun() -> ok end). 
<0.35.0> 
2> spawn(fun() -> ok end). 
<0.37.0> 
3> spawn(fun() -> ok end). 
<0.39.0> 
+0

不應該是第一句話中的「Pids can not be ..」嗎? – ZeissS 2010-11-18 08:12:13

+0

不,我的意思是我說的。 [VM]重新啓動時可以重複使用Pid。 – 2010-11-18 10:50:40