erlang四大behaviour之一gen_server(轉載)

erlang程序設計裏面有個設計原則就是把你的進程構造成樹,把共用代碼提出來,特定功能用自己的module實現,這也就是behaviour了,應用behaviour可以減少與本身事務無關的代碼量,設計邏輯更加清晰。老紀邊學習邊記錄吧。

gen_server實現服務器/客戶端模型,用於多個客戶共用一個資源的這種情況。他由幾個接口函數和幾個回調函數組成(回調函數必須在你的module裏定義)這些可以參考erlang的doc

舉個例子:

複製代碼

-module(ch3). 
%這是我們的回調模塊,也是我們實現業務邏輯的模塊-behaviour(gen_server). 
%說明我們應用gen_server這個behaviour-export([start_link/0]).
%-export([alloc/0, free/1]).
-export([init/1, handle_call/3, handle_cast/2]).  %gen_server 的導出函數

start_link() ->   
    gen_server:start_link({local, ch3}, ch3, [], []).

alloc() ->  
    gen_server:call(ch3, alloc).

free(Ch) ->   
    gen_server:cast(ch3, {free, Ch}).

init(_Args) ->    
    {ok, channels()}.

handle_call(alloc, _From, Chs) -> 
   {Ch, Chs2} = alloc(Chs),   
   {reply, Ch, Chs2}.

handle_cast({free, Ch}, Chs) -> 
    Chs2 = free(Ch, Chs),  
    {noreply, Chs2}.

複製代碼

 

gen_server:start_link的調用會生成一個服務器進程且連接到進程樹,並調用我們的init函數。

gen_server:call(ch3, alloc)的調用導致對handle_call的調用,這是同步的。

gen_server:cast(ch3, {free, Ch})的調用導致對handle_cast的調用,這是異步的。很簡單。

假如你不想把服務器進程掛入監控樹的話,直接用gen_server:start啓動進程,這是這個服務器進程就是一個普通進程了。

gen_server的停止規則:

  1. 以gen_server:start_link開始的連入監控樹:

  一般情況不需要提供自己的停止函數,監控進程會自動處理,但是如果你想在gen_server進程中自己清理以下資源,那麼就必須在init函數裏調 用process_flag(trap_exit, true)來捕獲退出信號,這會導致調用terminate(shutdown, State)函數,所以你也必須實現這個函數

  2. 以gen_server:start開始的單獨gen_server:

  終止他就比較簡單,直接調用gen_server:cast(Name, stop),這會導致調用handle_cast(stop, State),它的實現裏寫入 {stop, normal, State}即可,它最終導致terminate(normal, State)的調用,你的清理工作就可以在這繼續了。

 

erlang越看越喜歡,但是要深入要走的路還很長

 

 

本文屬轉載

原作者:老紀
原載:
老紀博客版權所有。轉載時必須以鏈接形式註明轉載自老紀博客 [http://www.jifuyi.com/]。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章