gen_server 启动:
gen_server 的启动是通过两个函数,一个是 gen_server:start()
, 一个是 gen_server:start_link()
.
两者的区别就在于start()
启动了一个单独的进而start_link()
使得两个进程link在了一起。
我们以start_link 为例,根据官方文档的描述, start_link 建立了连接到 supervisor 的一个进程,并且同步调用同模块下的init 函数,直到其返回才返回。
具体如下 :
1. gen_server:start_link()
调用 proc_lib:start_link()
创建了一个进程去执行init_it()
, 主进程阻塞receive 等待返回。
2. init_it()
函数执行了我们定义的 init()
函数,返回给主进程消息, 并且一直执行loop 函数等待 call, cast, 和info 消息。
gen_server:call
call 函数是一个同步调用。
假定是pid1 call pid2(gen_server进程)
进程Pid1 用`erlang:send()`发送给相应进程Pid2消息后, receive 等待返回, 此时Pid1 一直处于阻塞 状态。
Pid2 为一个gen_server 行为模式的进程。 loop 函数等待到消息后, 处理相应的逻辑, 并返回reply。
除去错误等情况, 经常会用到的就是 使用{noreply, …..}作为返回值, 之后用gen_server:reply 来返回call.
我当时一直不明白为什么需要有两种不同的处理方式,却明明有同样的效