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})

Другие вопросы по тегам