Erlang gen_server中{via,RegMod,ViaName}注册规范及示例求助
Erlang gen_server {via, RegMod, ViaName} 使用示例
1. 自定义注册表模块(RegMod)
先实现一个符合要求的注册表模块,这里用ETS表存储进程名与PID的映射:
-module(my_registry). -export([register_name/2, unregister_name/1, whereis_name/1, send/2]). % 初始化ETS表,首次注册时自动创建 init() -> ets:new(my_registry_table, [named_table, public, {read_concurrency, true}]). % 注册进程名与PID register_name(Name, Pid) when is_pid(Pid) -> case ets:insert_new(my_registry_table, {Name, Pid}) of true -> yes; false -> no end. % 注销进程名 unregister_name(Name) -> ets:delete(my_registry_table, Name), ok. % 根据进程名查找PID whereis_name(Name) -> case ets:lookup(my_registry_table, Name) of [{Name, Pid}] -> Pid; [] -> undefined end. % 向注册进程发送消息 send(Name, Msg) -> case whereis_name(Name) of undefined -> {badarg, {Name, Msg}}; Pid -> Pid ! Msg, ok end.
2. gen_server 中使用 {via, RegMod, ViaName} 注册
编写一个简单的gen_server,启动时通过自定义注册表完成进程注册:
-module(my_server). -behaviour(gen_server). -export([start_link/0, get_pid/0]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). % 启动gen_server,使用{via, my_registry, my_server_1}作为注册标识 start_link() -> % 初始化注册表(未初始化时执行) case ets:info(my_registry_table) of undefined -> my_registry:init(); _ -> ok end, gen_server:start_link({via, my_registry, my_server_1}, ?MODULE, [], []). % 通过自定义注册表获取进程PID get_pid() -> my_registry:whereis_name(my_server_1). % gen_server回调实现 init([]) -> {ok, []}. handle_call(_Request, _From, State) -> {reply, ok, State}. handle_cast(_Msg, State) -> {noreply, State}. handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, _State) -> % 进程终止时注销注册名 my_registry:unregister_name(my_server_1), ok. code_change(_OldVsn, State, _Extra) -> {ok, State}.
3. 测试验证
在Erlang Shell中执行以下命令验证:
% 编译模块 c(my_registry). c(my_server). % 启动gen_server my_server:start_link(). % 通过注册表获取进程PID my_server:get_pid(). % 返回对应的进程PID % 通过注册表直接给进程发消息 my_registry:send(my_server_1, test_msg).
关键说明
- RegMod必须实现的四个核心函数:
register_name/2(绑定名称与PID)、unregister_name/1(注销名称)、whereis_name/1(查询PID)、send/2(向注册进程发送消息),函数行为需与global模块对应函数一致。 - 示例用ETS实现了本地注册表,你也可以基于分布式存储、外部服务扩展出跨节点的进程注册逻辑。
内容的提问来源于stack exchange,提问作者孙海城
相关产品推荐
相关产品推荐

