2 votes

Impossible d'engendrer un processus en Erlang

Je ne sais pas vraiment pourquoi je n'y arrive pas, mais je suis sûr que la réponse est extraordinairement simple. Je suis juste en train de tester quelques trucs et j'ai découvert lors de mes tests que j'aimerais lancer un processus à l'intérieur de handle_info de mon gen_server .

Cependant, bien que j'aie essayé différentes combinaisons, le meilleur résultat que j'obtienne de mon enfant est de mourir avec une erreur et de renvoyer {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()]).

Mon premier objectif était de déterminer si plusieurs serveurs pouvaient être démarrés avec un seul module. Le second était de savoir si handle_info a été exécuté dans un processus séparé... pour une raison quelconque, quand j'ai lu qu'il était asynchrone, j'ai pensé qu'il était dans un autre processus. Maintenant le troisième est de créer un processus dans cet appel.

Ma coquille typique ressemble à quelque chose comme (avec des commentaires) :

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

J'ai utilisé hello/1 avec [] et _ , hello/0 . Ainsi que spawn/1 , spawn/3 , spawn_link/1 et spawn_link/3 ... J'ai utilisé ?MODULE , test , State et pour les rires {local, State} comme paramètre du module. Je me suis séparé de ce que j'ai vu sur plusieurs sites web et j'ai mis en fun hello/0 et fun hello/1 lors de la transmission de la fonction. Cela produit des plantages mais permet de se débarrasser de l'avertissement du compilateur.

Où ai-je fait fausse route ?

4voto

7stud Points 7467

Le troisième argument de spawn/3 est une liste contenant le nombre d'arguments que la fonction engendrée requiert. Par exemple, si la fonction engendrée prend 1 argument, la liste contiendra 1 argument ; et si la fonction engendrée prend 3 arguments, la liste contiendra 3 arguments. Enfin, si la fonction engendrée prend 0 argument, la liste contiendra 0 argument, c'est-à-dire la liste vide.

Vous avez défini hello comme ça :

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

C'est une fonction d'arité 1, et pas seulement cela, le seul argument qui correspond à la fonction est la liste vide. Pour passer un argument à une fonction que vous avez créée, vous devriez écrire :

spawn(?MODULE, hello ,[SomeArg])

Et, parce que vous voulez faire correspondre une fonction qui prend la liste vide comme seul argument, SomeArg doit être la liste vide :

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

Notez que la syntaxe de spawn/3 est MFA, ou nom de module, nom de fonction, arguments, qui est une liste contenant les arguments.

Ensuite, vous avez deux autres problèmes :

  1. Vous ne devriez pas appeler gen_server:start_link(bob) comme vous l'avez fait ici :

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

    Il n'existe pas de fonction telle que gen_server:start_link/1 . Au lieu de cela, vous devez appeler la fonction de votre interface utilisateur start_link/1 qui appelle ensuite gen_server:start_link/3 . Vous pourriez vouloir renommer la fonction de votre interface utilisateur my_gen_server_starter() afin que vous sachiez clairement ce qu'il fait.

  2. %% Me prévient que la fonction hello, sous quelque forme que ce soit, n'est pas utilisée.

    Vous devez exporter une fonction pour pouvoir la lancer. Comme vous n'avez pas exporté la fonction et qu'aucune fonction du module n'appelle la fonction, cela signifie que la fonction ne pourra jamais être exécutée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X