启动一个Gen_Server

在前一节中的代码,可以通过 ch3:start_link() 来启动这个gen_server:

  1. start_link() ->
  2. gen_server:start_link({local, ch3}, ch3, [], []) => {ok, Pid}

start_link 调用了函数 gen_server:start_link/4 。这个函数产生了一个新进程一个gen_server并联接到其上。

  • 第一个参数 {local,ch3} 指定了名称。在这种情况下,gen_srever将在本地被注册为 ch3 。如果忽略名称,那么这个gen_server就不会被注册了,这时就必须使用其pid。名称也可以以 {global,Name} 的形式给出,这种情况下gen_server则会使用 global:register_name/2 来进行注册。
  • 第二个参数, ch3, 则是回调模块的名字,也就是回调函数所放的那个模块。在这里,接口函数( start_link, alloc 和 free )和回调函数(init, handle_call 和 handle_cast)。一般来说这是好的编程实践,将代表同一个进程的代码包含在同一个模块中。
  • 第三个参数,[], 这个值将被原封不动传递给回调函数 init。在这里,init无须任何输入数据将忽略这个参数。
  • 第四个参数,[],是参数的列表。具体的参数请查看 gen_server(3) 。在注册名称成功后,新的gen_server进程会调用回调函数 ch3:init([]).init返回 {ok,State} ,其中 State 是gen_server的内部状态。在这里,状态就是可用的频道。
  1. init(_Args) ->
  2. {ok, channels()}.

注意 gen_server:start_link 是同步的。只有等到gen_server被完全初始化并准备接受请求之后才会返回。

如果gen_server是某棵监督树的一部分,即gen_server是由一个督程启动的,那么必须使用 gen_server:start_link 。还有另外一个函数 gen_server:start 用于启动一个独立的gen_server,即不是某棵监督树一部分的一个gen_server。