Не может вызвать процесс в Erlang - PullRequest
2 голосов
/ 27 февраля 2020

Я не совсем уверен, почему я не могу получить это, но я уверен, что ответ чрезвычайно прост. Я просто тестирую несколько вещей и в своих тестах обнаружил, что хотел бы создать процесс в пределах handle_info моего gen_server.

Однако, несмотря на то, что я пробую разные комбинации, лучший результат я получение от моего ребенка умирает с ошибкой и возвращает {undef, [{bob, hello, [], []}]}.

код:

-module(test).
-behaviour(gen_server).
-export([start_link/1, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

start_link(Args) ->
    gen_server:start_link({local, Args}, ?MODULE, Args, []).

init(Args) ->
    io:format("Init ~p ~p~n",[self(), Args]),
    {ok, Args}.

handle_call(_, _, State) ->
    io:format("Call ~p~n",[self()]),
    {reply, ok, State}.

handle_cast(_, State) ->
    io:format("Cast ~p~n",[self()]),
    {noreply, State}.

handle_info(_, State) ->
    io:format("Info ~p~n",[self()]),
    spawn(?MODULE,fun hello/1,[]),
    {noreply, State}.

terminate(_, _) ->
    ok.

code_change(_, State, _) ->
    {ok, State}.

hello([]) ->
    io:format("WOOT ~p~n",[self()]).

Моей первой целью было определить, можно ли запустить несколько серверов с одного модуля. Вторым было, если handle_info был выполнен в отдельном процессе ... по какой-то причине, когда я читал, что это было асинхронно, я думал, что это было в другом процессе. Теперь третье - запустить процесс в этом вызове.

Моя типичная оболочка выглядит примерно так (с комментариями):

> c(test), {ok, P} = gen_server:start_link(bob)
> %% Warns me the function hello in any incarnation is not used
> P ! woot.
> %% An error of some kind depending on what I've done
> f(P), gen_server:stop(bob).

Я использовал hello/1 с [] и _, hello/0. Кроме spawn/1, spawn/3, spawn_link/1 и spawn_link/3 ... Я использовал ?MODULE, test, State и для смеха {local, State} в качестве параметра модуля. Я расстался с тем, что видел на нескольких веб-сайтах, и вставил fun hello/0 и fun hello/1 при прохождении функции. Это приводит к сбоям, но избавляется от предупреждения компилятора.

Где я go ошибся?

1 Ответ

4 голосов
/ 27 февраля 2020

Третий аргумент spawn / 3 - это список, содержащий количество аргументов, которое требуется для вызываемой функции. Например, если порожденная функция принимает 1 аргумент, список будет содержать 1 аргумент; и если порожденная функция принимает 3 аргумента, список будет содержать 3 аргумента. Наконец, если порожденная функция принимает 0 аргументов, список будет содержать 0 аргументов, т.е. пустой список.

Вы определили hello следующим образом:

hello([]) ->
    io:format("WOOT ~p~n",[self()]).

Это функция с арностью 1, и не только это, единственный аргумент, который соответствует функции, это пустой список. Чтобы передать один аргумент в функцию, которую вы породили, вы должны написать:

spawn(?MODULE, hello ,[SomeArg])

И, поскольку вы хотите сопоставить функцию, которая принимает пустой список в качестве единственного аргумента, SomeArg должен быть пустым списком:

spawn(?MODULE, hello, [[]])

Обратите внимание, что синтаксис для spawn/3 - это MFA или имя модуля, имя функции, arguments, представляющий собой список, содержащий аргументы.

Далее, у вас есть еще две проблемы:

  1. Вы не должны вызывать gen_server:start_link(bob), как вы это делали здесь:

    {ok, P} = gen_server:start_link(bob)
    

    Нет такой функции, как gen_server:start_link/1. Вместо этого вам нужно вызвать функцию пользовательского интерфейса start_link/1, которая затем вызывает gen_server:start_link/3. Возможно, вы захотите переименовать функцию пользовательского интерфейса my_gen_server_starter(), чтобы вы знали, что она делает.

  2. %% Предупреждает, что функция «Привет» в любом воплощении не used

    Вы должны экспортировать функцию, чтобы иметь возможность ее порождать. Поскольку вы не экспортировали функцию и поскольку никакие функции внутри модуля не вызывают функцию, это означает, что функция никогда не сможет быть выполнена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...