Erlang OTP(五) gen_server小结

调用关系:

通用服务器模块(gen_server)                              回调模块(my_bank) 

gen_server:start_link             ------------>             Module:init/1 gen_server:call gen_server:multi_call            ------------>             Module:handle_call/3

gen_server:cast

gen_server_abcast                ------------>             Module:handle_cast/2

--                                            ------------>             Module:handle_info/2

--                                            ------------>             Module:terminate/2                               

--                                            ------------>             Module:code_change/3

当回调函数调用失败或返回错误值时,gen_server会中止。 gen_server不会自动跟踪退出信号。 

        gen_server行为模式的基本流程如下:

        回调模块的start调用gen_server:start_link(或gen_server:start)来启动服务器,并进入主循环,在回调模块的接口函数(处理具体的业务逻辑)中调用gen_server的call或cast来处理请求,在gen_server的call和cast中进一步调用回调模块中的handle_call和handle_cast来执行具体的业务逻辑处理,回调模块的terminate来终止进程。 

gen_server:start_link:

        start()函数对应的回调函数是init/1,一般来说是进行服务器启动后的一些初始化的工作, 并生成初始的状态State,正常返回是{ok, State}。这个State是贯穿整个服务器, 并把所有六个回调函数联系起来的纽带。它的值最初由init/1生成, 此后可以由三个handle函数修改,每次修改后又要放回返回值中, 供下一个被调用的handle函数使用。 如果init/1返回ignore{stop, Reason},则会中止服务器的启动。有一点细节要注意的是,API函数和回调函数虽然习惯上是写在同一个文件中,但执行函数 的进程却通常是不一样的。在上面的模板中,start_link/0中使用self()的话,显示的是调用者的进程号,而在init/1中使用self()的话,显示的是服务器的进程号。

gen_server:multi_call:

        call对应的回调函数handle_call/3在正常情况下的返回值是{reply,Reply,NewState}, Reply会作为call的返回值传递回去,NewState则会作为服务器的状态。 另外还可以使用{stop, Reason, State}中止服务器运行,这比较少用。

使用call要小心的是,两个服务器进程不能互相call,不然可能会出现死锁。

gen_server:cast:

        cast是没有返回值的调用,一般把它叫做通知。它是一个“异步”的调用,调用后会直接收到 ok,无需等待回调函数执行完毕。它的形式是gen_server:cast(ServerRef, Request)。参数含义 与call相同。由于不需要等待返回,所以没必要设置超时,没有第三个参数。在多节点的情况下,可以用abcast,向各节点上的具有指定名字的服务进程发通知。 

        cast们对应的回调函数是handle_cast/2,具体为:handle_cast(Msg, State)。 第一个参数是由cast传进去的,第二个是服务器状态,和call类似。handel_cast/2的返回值通常是{noreply, NewState},这可以用来改变服务器状态, 或是{stop, Reason, NewState},这会停止服务器。通常来说,停止服务器的命令用 cast来实现比较多。

原生消息

        原生消息是指不通过call或cast,直接发往服务器进程的消息。 比方说别的进程用!发过来的消息、跟服务器建立链接的进程死掉了, 发来{'EXIT', Pid, Why}等等。一般写程序要尽量用API,不要直接用!向服务器进程发消息, 但对于socket一类的依赖于消息的应用,就不得不处理原生消息了。

        原生消息使用handle_info/2处理,具体为handle_info(Info, State)。其中Info是 发过来的消息的内容。回复和handle_cast是一样的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值