Gproc: каждый процесс просто возвращает свой pid при выполнении lookup_pids
Я попытался зарегистрировать некоторые процессы с семейным именем с помощью gproc. По этой причине я создал gen_server, который содержит две функции: первая - для обработки регистрации, а вторая - для поиска PID зарегистрированных процессов. После этого я открыл две консоли erlang и зарегистрировал два процесса с одинаковым свойством (каждая консоль запрашивает у сервера зарегистрировать один процесс). Мой код сервера выглядит следующим образом:
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [],[]).
init([]) -> gproc:start_link(), {ok, []}.
%% Synchronous call
register(Pid, Name) ->
gen_server:call(Pid, {register, Name}).
getpids(Pid, Name) ->
gen_server:call(Pid, {getpids, Name}).
handle_call({register, Name}, _From, State) ->
gproc:reg_or_locate({p,l,Name}),
{reply, Name, State};
handle_call({getpids, Name}, _From, State) ->
Pids = gproc:lookup_pids({p,l,Name}),
{reply, Pids, State}.
handle_info(Msg, State) ->
io:format("Unexpected message: pn",[Msg]),
{noreply, State}.
terminate(normal, State) ->
ok.
Я зарегистрировал свои процессы в
server_name:register(PID,<<"test">>)
и я ищу пидс с:
server_name:getpids(PID,<<"test">>)
Но когда я попытался получить pid своих семейных процессов (в основном я должен получить список из 2 pids), я получил только один pid (каждая консоль просто просматривает pid, зарегистрированный им самостоятельно, и не отображает pid, зарегистрированный на другой консоли).).
Спасибо за вашу помощь. С уважением.
1 ответ
Я думаю, что правильный способ запустить приложение gproc - это использовать:
application:start(gproc),
Далее, я предполагаю, что когда вы говорите, что открываете 2 консоли erlang, вы запускаете 2 узла erlang (в linux запуск erl на 2 консолях). В этом случае вам сначала нужно соединить 2 узла в кластере, например:
В консоли 1
erl -sname node1
тогда вы получите приглашение оболочки erlang с именем узла: host_name@node1
в консоли 2
erl -sname node2
затем вы получите приглашение оболочки erlang с именем узла: host_name@node2
все еще в узле 2:
true = net_kernel:connect_node('host_name@node1').
application:start(gproc).
Теперь 2 узла erlang соединены, и приложение gproc запущено, вы можете регистрировать процессы.
Я не уверен, что правильно использовать функцию gproc:reg_or_locate/1
чтобы зарегистрировать несколько процессов с одним и тем же ключом, я бы использовал gproc:reg/1
,
То же самое для контекста регистрации, я бы использовал global: gproc:reg({p,g,Name})