在Erlang中如何解释未定义错误?

在Erlang中如何解释未定义错误?,erlang,undef,Erlang,Undef,我试图理解以下错误: 4> c(sv). {ok,sv} 5> B=sv:start(). <0.93.0> 6> =ERROR REPORT==== 14-Jul-2020::21:44:13.256000 === Error in process <0.93.0> with exit value: {undef,[{common,createProcess, [{monitor,monitor,

我试图理解以下错误:

4> c(sv).
{ok,sv}
5> B=sv:start().
<0.93.0>
6> =ERROR REPORT==== 14-Jul-2020::21:44:13.256000 ===
Error in process <0.93.0> with exit value:
{undef,[{common,createProcess,
                [{monitor,monitor,
                          {monstate,undefined,undefined,undefined,true,
                                    undefined,false}}],
                []},
        {sv,server,1,[{file,"sv.erl"},{line,14}]}]}
普通。erl

%%% common functionality module
-module(common).
-export([createProcess/1]).
-import(worker,[worker/1]).
-import(monitor,[monitor/1]).
-include("records.hrl").

createProcess({M,F,A})->
    Pid=spawn(M,F,[A]),
    Ref=erlang:monitor(process,Pid),
    {Pid,Ref}.
-record(monstate,{
    queue,
    qc,
    wpid,
    free=true,
    wref,
    init=false
}).

-record(sstate,{
    init=false,
    mpid=null,
    mref=null
}).
-module(sv).
-import(common,[createProcess/1]).
-include("records.hrl").
-export([start/0,server/1]).



start()->
    spawn(?MODULE,server,[#sstate{init=false}]).

server(State=#sstate{init=I})when I=:=false ->
    {MPid,MRef}=createProcess({monitor,monitor,#monstate{init=false}}),
    server(State#sstate{init=true,mpid=MPid,mref=MRef});

server(State=#sstate{mpid=MPid,mref=MRef})->
    receive
           {From,state}->From ! State,
                            server(State);
           {From,Message}-> MPid ! {request,{From,Message}},
                            server(State);
                
            {'DOWN',MRef,process,MPid,_}-> {NewMPid,NewMRef}=createProcess({?MODULE,monitor,#monstate{init=false}}),
                                            server(State#sstate{mpid=NewMPid,mref=NewMRef});
            _ ->exit(invalid_message)
                                    
    end.
%%% servers as both a gen_server that can be queried  and a supervisor for its worker process
-module(monitor).
-export([monitor/1]).
-import(common,[createProcess/1]).

-include("records.hrl").

-define(QUEUE_SIZE,5).

tryEnqueue(Message,MState=#monstate{queue=Q,qc=C}) when C<?QUEUE_SIZE->
    NewQueue=queue:in(Message,Q),
    {queued,MState#monstate{qc=C+1,queue=NewQueue}};
tryEnqueue(_,MState)->{queue_full,MState}.

monitor(MState=#monstate{wpid=_,wref=_,init=I}) when I=:= false ->
    {WorkerPid,WorkerRef}=createProcess({worker,worker,self()}),
    monitor(MState#monstate{wpid=WorkerPid,wref=WorkerRef,init=true,qc=0,queue=queue:new()});

monitor(MState=#monstate{wpid=W,free=Free,wref=Ref,queue=Q,qc=C})->
    receive
        
        {request,{From ,Message}} -> case Free of 
                                            true -> W ! {From,Message},
                                                    monitor(MState#monstate{free=false});
                                                                             
                                            false -> 
                                                     St=case tryEnqueue({From,Message},MState) of 
                                                            {queue_full,S} -> From ! {queue_full,Message},S;
                                                            {queued,S} -> S
                                                        end,
                                                      monitor(St)
                                      end;
                                         
                                        
                                      
                                  
        {worker,{finished,_}}-> case queue:out(Q) of
                                    {{_,Element},Rest} -> W ! Element,
                                                          monitor(MState#monstate{free=false,queue=Rest,qc=C-1});
                                    {empty,Rest}       -> monitor(MState#monstate{free=true,queue=Rest})
                                end;

        {'DOWN',Ref,process,_,_}->
             {NewWorkerPid,NewWorkerRef}=createProcess({?MODULE,worker,self()}),
             monitor(MState#monstate{wpid=NewWorkerPid,wref=NewWorkerRef,free=true});

        _->exit(invalid_message)

    end.
记录。hrl

%%% common functionality module
-module(common).
-export([createProcess/1]).
-import(worker,[worker/1]).
-import(monitor,[monitor/1]).
-include("records.hrl").

createProcess({M,F,A})->
    Pid=spawn(M,F,[A]),
    Ref=erlang:monitor(process,Pid),
    {Pid,Ref}.
-record(monstate,{
    queue,
    qc,
    wpid,
    free=true,
    wref,
    init=false
}).

-record(sstate,{
    init=false,
    mpid=null,
    mref=null
}).
-module(sv).
-import(common,[createProcess/1]).
-include("records.hrl").
-export([start/0,server/1]).



start()->
    spawn(?MODULE,server,[#sstate{init=false}]).

server(State=#sstate{init=I})when I=:=false ->
    {MPid,MRef}=createProcess({monitor,monitor,#monstate{init=false}}),
    server(State#sstate{init=true,mpid=MPid,mref=MRef});

server(State=#sstate{mpid=MPid,mref=MRef})->
    receive
           {From,state}->From ! State,
                            server(State);
           {From,Message}-> MPid ! {request,{From,Message}},
                            server(State);
                
            {'DOWN',MRef,process,MPid,_}-> {NewMPid,NewMRef}=createProcess({?MODULE,monitor,#monstate{init=false}}),
                                            server(State#sstate{mpid=NewMPid,mref=NewMRef});
            _ ->exit(invalid_message)
                                    
    end.
%%% servers as both a gen_server that can be queried  and a supervisor for its worker process
-module(monitor).
-export([monitor/1]).
-import(common,[createProcess/1]).

-include("records.hrl").

-define(QUEUE_SIZE,5).

tryEnqueue(Message,MState=#monstate{queue=Q,qc=C}) when C<?QUEUE_SIZE->
    NewQueue=queue:in(Message,Q),
    {queued,MState#monstate{qc=C+1,queue=NewQueue}};
tryEnqueue(_,MState)->{queue_full,MState}.

monitor(MState=#monstate{wpid=_,wref=_,init=I}) when I=:= false ->
    {WorkerPid,WorkerRef}=createProcess({worker,worker,self()}),
    monitor(MState#monstate{wpid=WorkerPid,wref=WorkerRef,init=true,qc=0,queue=queue:new()});

monitor(MState=#monstate{wpid=W,free=Free,wref=Ref,queue=Q,qc=C})->
    receive
        
        {request,{From ,Message}} -> case Free of 
                                            true -> W ! {From,Message},
                                                    monitor(MState#monstate{free=false});
                                                                             
                                            false -> 
                                                     St=case tryEnqueue({From,Message},MState) of 
                                                            {queue_full,S} -> From ! {queue_full,Message},S;
                                                            {queued,S} -> S
                                                        end,
                                                      monitor(St)
                                      end;
                                         
                                        
                                      
                                  
        {worker,{finished,_}}-> case queue:out(Q) of
                                    {{_,Element},Rest} -> W ! Element,
                                                          monitor(MState#monstate{free=false,queue=Rest,qc=C-1});
                                    {empty,Rest}       -> monitor(MState#monstate{free=true,queue=Rest})
                                end;

        {'DOWN',Ref,process,_,_}->
             {NewWorkerPid,NewWorkerRef}=createProcess({?MODULE,worker,self()}),
             monitor(MState#monstate{wpid=NewWorkerPid,wref=NewWorkerRef,free=true});

        _->exit(invalid_message)

    end.
sv.erl

%%% common functionality module
-module(common).
-export([createProcess/1]).
-import(worker,[worker/1]).
-import(monitor,[monitor/1]).
-include("records.hrl").

createProcess({M,F,A})->
    Pid=spawn(M,F,[A]),
    Ref=erlang:monitor(process,Pid),
    {Pid,Ref}.
-record(monstate,{
    queue,
    qc,
    wpid,
    free=true,
    wref,
    init=false
}).

-record(sstate,{
    init=false,
    mpid=null,
    mref=null
}).
-module(sv).
-import(common,[createProcess/1]).
-include("records.hrl").
-export([start/0,server/1]).



start()->
    spawn(?MODULE,server,[#sstate{init=false}]).

server(State=#sstate{init=I})when I=:=false ->
    {MPid,MRef}=createProcess({monitor,monitor,#monstate{init=false}}),
    server(State#sstate{init=true,mpid=MPid,mref=MRef});

server(State=#sstate{mpid=MPid,mref=MRef})->
    receive
           {From,state}->From ! State,
                            server(State);
           {From,Message}-> MPid ! {request,{From,Message}},
                            server(State);
                
            {'DOWN',MRef,process,MPid,_}-> {NewMPid,NewMRef}=createProcess({?MODULE,monitor,#monstate{init=false}}),
                                            server(State#sstate{mpid=NewMPid,mref=NewMRef});
            _ ->exit(invalid_message)
                                    
    end.
%%% servers as both a gen_server that can be queried  and a supervisor for its worker process
-module(monitor).
-export([monitor/1]).
-import(common,[createProcess/1]).

-include("records.hrl").

-define(QUEUE_SIZE,5).

tryEnqueue(Message,MState=#monstate{queue=Q,qc=C}) when C<?QUEUE_SIZE->
    NewQueue=queue:in(Message,Q),
    {queued,MState#monstate{qc=C+1,queue=NewQueue}};
tryEnqueue(_,MState)->{queue_full,MState}.

monitor(MState=#monstate{wpid=_,wref=_,init=I}) when I=:= false ->
    {WorkerPid,WorkerRef}=createProcess({worker,worker,self()}),
    monitor(MState#monstate{wpid=WorkerPid,wref=WorkerRef,init=true,qc=0,queue=queue:new()});

monitor(MState=#monstate{wpid=W,free=Free,wref=Ref,queue=Q,qc=C})->
    receive
        
        {request,{From ,Message}} -> case Free of 
                                            true -> W ! {From,Message},
                                                    monitor(MState#monstate{free=false});
                                                                             
                                            false -> 
                                                     St=case tryEnqueue({From,Message},MState) of 
                                                            {queue_full,S} -> From ! {queue_full,Message},S;
                                                            {queued,S} -> S
                                                        end,
                                                      monitor(St)
                                      end;
                                         
                                        
                                      
                                  
        {worker,{finished,_}}-> case queue:out(Q) of
                                    {{_,Element},Rest} -> W ! Element,
                                                          monitor(MState#monstate{free=false,queue=Rest,qc=C-1});
                                    {empty,Rest}       -> monitor(MState#monstate{free=true,queue=Rest})
                                end;

        {'DOWN',Ref,process,_,_}->
             {NewWorkerPid,NewWorkerRef}=createProcess({?MODULE,worker,self()}),
             monitor(MState#monstate{wpid=NewWorkerPid,wref=NewWorkerRef,free=true});

        _->exit(invalid_message)

    end.
监视器.erl

%%% common functionality module
-module(common).
-export([createProcess/1]).
-import(worker,[worker/1]).
-import(monitor,[monitor/1]).
-include("records.hrl").

createProcess({M,F,A})->
    Pid=spawn(M,F,[A]),
    Ref=erlang:monitor(process,Pid),
    {Pid,Ref}.
-record(monstate,{
    queue,
    qc,
    wpid,
    free=true,
    wref,
    init=false
}).

-record(sstate,{
    init=false,
    mpid=null,
    mref=null
}).
-module(sv).
-import(common,[createProcess/1]).
-include("records.hrl").
-export([start/0,server/1]).



start()->
    spawn(?MODULE,server,[#sstate{init=false}]).

server(State=#sstate{init=I})when I=:=false ->
    {MPid,MRef}=createProcess({monitor,monitor,#monstate{init=false}}),
    server(State#sstate{init=true,mpid=MPid,mref=MRef});

server(State=#sstate{mpid=MPid,mref=MRef})->
    receive
           {From,state}->From ! State,
                            server(State);
           {From,Message}-> MPid ! {request,{From,Message}},
                            server(State);
                
            {'DOWN',MRef,process,MPid,_}-> {NewMPid,NewMRef}=createProcess({?MODULE,monitor,#monstate{init=false}}),
                                            server(State#sstate{mpid=NewMPid,mref=NewMRef});
            _ ->exit(invalid_message)
                                    
    end.
%%% servers as both a gen_server that can be queried  and a supervisor for its worker process
-module(monitor).
-export([monitor/1]).
-import(common,[createProcess/1]).

-include("records.hrl").

-define(QUEUE_SIZE,5).

tryEnqueue(Message,MState=#monstate{queue=Q,qc=C}) when C<?QUEUE_SIZE->
    NewQueue=queue:in(Message,Q),
    {queued,MState#monstate{qc=C+1,queue=NewQueue}};
tryEnqueue(_,MState)->{queue_full,MState}.

monitor(MState=#monstate{wpid=_,wref=_,init=I}) when I=:= false ->
    {WorkerPid,WorkerRef}=createProcess({worker,worker,self()}),
    monitor(MState#monstate{wpid=WorkerPid,wref=WorkerRef,init=true,qc=0,queue=queue:new()});

monitor(MState=#monstate{wpid=W,free=Free,wref=Ref,queue=Q,qc=C})->
    receive
        
        {request,{From ,Message}} -> case Free of 
                                            true -> W ! {From,Message},
                                                    monitor(MState#monstate{free=false});
                                                                             
                                            false -> 
                                                     St=case tryEnqueue({From,Message},MState) of 
                                                            {queue_full,S} -> From ! {queue_full,Message},S;
                                                            {queued,S} -> S
                                                        end,
                                                      monitor(St)
                                      end;
                                         
                                        
                                      
                                  
        {worker,{finished,_}}-> case queue:out(Q) of
                                    {{_,Element},Rest} -> W ! Element,
                                                          monitor(MState#monstate{free=false,queue=Rest,qc=C-1});
                                    {empty,Rest}       -> monitor(MState#monstate{free=true,queue=Rest})
                                end;

        {'DOWN',Ref,process,_,_}->
             {NewWorkerPid,NewWorkerRef}=createProcess({?MODULE,worker,self()}),
             monitor(MState#monstate{wpid=NewWorkerPid,wref=NewWorkerRef,free=true});

        _->exit(invalid_message)

    end.
%%%服务器既是可以查询的gen_服务器,又是其工作进程的主管
-模块(监视器)。
-导出([monitor/1])。
-导入(通用,[createProcess/1])。
-包括(“records.hrl”)。
-定义(队列大小,5)。

tryEnqueue(Message,MState=#monstate{queue=Q,qc=C})当C错误表示
common:createProcess/1
未定义时。 发生这种情况很可能是因为以前没有在代码服务器中加载模块
common

运行
c(公共)。
也运行


请记住,
-import
compile指令仅意味着此模块中对函数X/Y的
调用将由模块作为模块X/Y执行,但不会创建模块依赖关系

如果模块
a
导入模块
B
,我仍然无法获取,为什么我需要单独编译模块
B
?无论如何,在编译了
common
模块之后,我得到了一个无限循环,仍然是
undef
。我的模块应该导入到哪里?它们不应该在调用
生成的模块中吗?(在我的例子中,
common
)@bercoviciardian Erlang
import
一点也不像Python
import
;它不需要能够调用其他模块的函数。事实上,它从来都不需要——它只是为了方便而提供的,坦率地说,你永远不应该使用它。在Erlang中,
import
所做的全部工作就是使另一个模块的函数不需要
module:
前缀就可以调用。有关详细说明,请参阅。@Bercovicadrian如果监视器模块也未加载,生成的进程将终止,并提示生成另一个进程。。。等等(另外,+1为了避免使用
import,
这会严重影响易读性,因为您必须检查它,以了解呼叫是本地的还是远程的,有些模块相当大)那么,当有很多模块时,您是否会逐个加载它们?这似乎不切实际。@Bercovicadrian您不相信多节点、>80个模块、erlang服务是以这种方式启动的,是吗?。模块在应用程序中分组,这些应用程序又形成一个版本。rrelease是一个拥有编译代码和引导脚本的版本。检查和后面的那些