【问题标题】:Can't spawn process in Erlang无法在 Erlang 中生成进程
【发布时间】:2020-02-27 04:59:40
【问题描述】:

我不太确定为什么我不能得到这个,但我确信答案非常简单。我只是在测试一些东西,在我的测试中发现我想在我的gen_serverhandle_info 中生成一个进程。

然而,尽管我尝试了不同的组合,但我从孩子身上得到的最好结果是因错误而死并返回 {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 在单独的进程中执行......由于某种原因,当我阅读它是异步的时,我认为它在另一个进程中。现在第三个是在该调用中生成一个进程。

我的典型外壳类似于(使用 cmets):

> 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/1spawn/3spawn_link/1spawn_link/3...我使用?MODULEtestState 和笑声{local, State} 作为模块参数。我已经放弃了我在多个网站上看到的内容,并在传递函数时输入了fun hello/0fun hello/1。这会产生崩溃,但消除了编译器警告。

我哪里做错了?

【问题讨论】:

    标签: erlang


    【解决方案1】:

    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,即模块名、函数名、参数,这是一个包含参数的列表。

    接下来,你还有两个问题:

    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. %% 警告我没有使用任何形式的函数 hello

      您必须导出一个函数才能生成它。因为你没有导出函数,并且模块内没有函数调用函数,这意味着函数永远无法执行。

    【讨论】:

    • 在我尝试的组合中,我一定是通过错误的大脑记忆输入了#1。我也确实在某些时候将参数正确匹配到我的spawn 调用。这是我看到的多个页面上的详细信息。解决方案是#2。我只是从 IDE 中复制/粘贴并删除了所有绒毛……我通常使用export_all……我不知道我需要多长时间才能确定解决方案。
    猜你喜欢
    • 1970-01-01
    • 2015-01-03
    • 2014-08-29
    • 2014-12-22
    • 2011-04-23
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    相关资源
    最近更新 更多