2011-04-20 80 views
2

我有gen_server:二郎停止gen_server

start(UserName) -> 
    case gen_server:start({global, UserName}, player, [], []) of 
    {ok, _} -> 
     io:format("Player: " ++ UserName ++ " started"); 
    {error, Error} -> 
     Error 
    end 
    ... 

現在我想編寫函數來停止這個根服務器。我有:

stop(UserName) -> 
    gen_server:cast(UserName, stop). 

handle_cast(stop, State) -> 
    {stop, normal, State}; 
handle_cast(_Msg, State) -> 
    {noreply, State}. 

我運行它:

start("shk"). 
Player: shk startedok 
stop(shk). 
ok 
start("shk"). 
{already_started,<0.268.0>} 

但是:

stop(player). 
ok 

就是工作。

如何通過名稱運行gen_server並按名稱停止?

謝謝。

回答

14

首先:您必須始終使用相同的名稱來處理進程,因此"foo"foo是不同的,因此請從嚴格的命名約定開始。

第二:使用全局註冊的進程時,還需要使用{global, Name}進行尋址過程。

在我看來,你也應該將stop函數轉換爲使用gen_server:call,它會阻止並讓你從gen_server返回一個值。舉例:

stop(Name) -> 
    gen_server:call({global, Name}, stop). 

handle_call(stop, _From, State) -> 
    {stop, normal, shutdown_ok, State} 

這將返回shutdown_ok給調用者。

這就是說,global模塊是相當有限的,替代品如gproc提供更好的分佈。

+0

gen_server具有特殊功能,可以停止/ 1,stop/3 http://erlang.org/doc/man/gen_server.html#stop-1 – 2016-05-20 12:43:25

1

我沒有面向我的文檔,但我的猜測是你需要將用戶名包裝在gen_server轉換中的全局元組中。