简体   繁体   English

无法在 Erlang 中生成进程

[英]Can't spawn process in Erlang

I'm not quite sure why I can't get this but I'm sure the answer is extraordinarily simple.我不太确定为什么我不能得到这个,但我相信答案非常简单。 I'm just testing out a few things and in my tests discovered that I would like to spawn a process within handle_info of my gen_server .我只是测试了一些东西,在我的测试中发现我想在我的gen_server handle_info中生成一个进程。

However despite me trying different combinations the best result I'm getting from my child is dying with an error and returning {undef, [{bob, hello, [], []}]} .然而,尽管我尝试了不同的组合,但我从孩子那里得到的最好结果是因错误而死亡并返回{undef, [{bob, hello, [], []}]}

Code:代码:

-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()]).

My first goal was to determine if multiple servers could be started with one module.我的第一个目标是确定是否可以使用一个模块启动多个服务器。 The second was if handle_info was executed in a separate process... for some reason when I read it was asynchronous I thought it was in another process.第二个是如果handle_info是在一个单独的进程中执行的……出于某种原因,当我读到它是异步的时,我以为它在另一个进程中。 Now the third is to spawn a process within that call.现在第三个是在该调用中生成一个进程。

My typical shell goes something like (with comments):我的典型 shell 类似于(带注释):

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

I've used hello/1 with [] and _ , hello/0 .我已经将hello/1[]_hello/0 As well as spawn/1 , spawn/3 , spawn_link/1 and spawn_link/3 ... I've used ?MODULE , test , State and for chuckles {local, State} as the module parameter.除了spawn/1spawn/3spawn_link/1spawn_link/3 ......我使用?MODULEtestState和笑声{local, State}作为模块参数。 I've parted with what I've seen on multiple websites and put in fun hello/0 and fun hello/1 when passing the function.我已经放弃了我在多个网站上看到的内容,并在传递函数时输入了fun hello/0fun hello/1 This produces crashes but got rid of the compiler warning.这会产生崩溃但摆脱了编译器警告。

Where did I go wrong?我哪里做错了?

The third argument to spawn/3 is a list containing the number of arguments which the spawned function requires. spawn/3的第三个参数是一个列表,其中包含生成的函数所需的参数数量。 For instance, if the spawned function takes 1 argument, the list will contain 1 argument;例如,如果生成的函数接受 1 个参数,则列表将包含 1 个参数; and if the spawned function takes 3 arguments, the list will contain 3 arguments.如果生成的函数接受 3 个参数,则列表将包含 3 个参数。 Finally, if the spawned function takes 0 arguments, the list will contain 0 arguments, ie the empty list.最后,如果生成的函数接受 0 个参数,则列表将包含 0 个参数,即空列表。

You defined hello like this:你这样定义hello

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

That's a function with arity 1, and not only that, the only argument that matches the function is the empty list.这是一个 arity 1 的函数,不仅如此,与该函数匹配的唯一参数是空列表。 In order to pass one argument to a function that you spawn, you would have to write:为了将一个参数传递给您生成的函数,您必须编写:

spawn(?MODULE, hello ,[SomeArg])

And, because you want to match a function that takes the empty list as its only argument, SomeArg has to be the empty list:并且,因为您想要匹配一个将空列表作为其唯一参数的函数,所以 SomeArg 必须是空列表:

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

Note that the syntax for spawn/3 is MFA, or module name, function name, arguments, which is a list containing the arguments.请注意spawn/3的语法是 MFA,或模块名称、函数名称、参数,它是一个包含参数的列表。

Next, you have two more problems:接下来,您还有两个问题:

  1. You shouldn't call gen_server:start_link(bob) as you did here:你不应该像这里那样调用gen_server:start_link(bob)

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

    There is no such function as gen_server:start_link/1 .没有像gen_server:start_link/1这样的函数。 Instead, you need to call your user interface function start_link/1 , which then calls gen_server:start_link/3 .相反,您需要调用您的用户界面函数start_link/1 ,然后调用gen_server:start_link/3 You might want to rename your user interface function my_gen_server_starter() , so that you are clear about what it does.您可能想要重命名您的用户界面函数my_gen_server_starter() ,以便您清楚它的作用。

  2. %% Warns me the function hello in any incarnation is not used %% 警告我没有使用任何化身中的函数 hello

    You have to export a function to be able to spawn it.您必须导出一个函数才能生成它。 Because you didn't export the function and because no functions inside the module call the function, that means the function can never execute.因为您没有导出该函数,并且模块内没有函数调用该函数,这意味着该函数永远无法执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM