日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用go来实现类似erlang otp里面的gen_server功能

發布時間:2024/1/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用go来实现类似erlang otp里面的gen_server功能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

erlang比go要成熟,其中一大原因就是擁有otp工程,進程的管理可以通過專門的行為

模式去處理,例如gen_server,里面包含的6個回調函數init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3

來實現進程的一系列行為,例如啟動進程,異步調用,同步調用,響應,關閉進程等

先來看一段gen_server的內部實現代碼:

-module(server_templat -export([start/1]). -export([call/2, cast/2]). -export([init/1]).%%通用進程模式(可以認為是c/s模型的阻塞和非阻塞)start(Mod) ->spawn(server_template, init, [Mod]). init(Mod) ->register(Mod, self()),State = Mod:init(),loop(Mod, State).loop(Mod, State) ->receive{call, From, Req} ->{Res, State2} = Mod:handle_call(Req, State),From ! {Mod, Res},loop(Mod, State2);{cast, Req} ->State2 = Mod:handle_cast(Req, State),loop(Mod, State2);stop -> stop end.%% 接口部分 call(Name, Req) ->Name ! {call, self(), Req},receive %% 這里就是阻塞在等待返回,精辟!!!{Name, Res} ->Resend. cast(Name, Req) ->Name ! {cast, Req},ok.

  

能看懂erlang代碼的,應該明白上面是什么意思。

下面是我用go來實現的

package globalimport ("time" )type PidObj struct {Callback GenServerreqCh chan GenReqreplyCh chan Replystop bool }type GenReq struct {Method stringMsgData interface{}t inttime int32 }type Reply interface{}const (call = iotacasttimershutdown )// Start server func RegisterPid(pidName interface{}, callback GenServer) *PidObj {pidObj := &PidObj{Callback:callback}pidObj.reqCh = make(chan GenReq, 1024)pidObj.replyCh = make(chan Reply, 1024)callback.Start()go pidObj.loop()return pidObj }func (p *PidObj) loop() {for {req := <-p.reqChswitch req.t {case call:reply := p.Callback.HandleCall(req)p.replyCh <- replycase cast:p.Callback.HandleCast(req)case timer:p.Callback.HandleInfo(req)//time.AfterFunc(time.Duration(req.time) * time.Second, func() {// p.Callback.HandleInfo(req)//})case shutdown:p.stop = trueclose(p.reqCh)close(p.replyCh)p.Callback.Stop()return}} }func (p *PidObj) Call(method string, msg interface{}) (reply Reply) {p.reqCh <- GenReq{Method: method, MsgData: msg, t: call}reply = <-p.replyChreturn }func (p *PidObj) Cast(method string, msg interface{}) {p.reqCh <- GenReq{Method: method, MsgData: msg, t: cast} }func (p *PidObj) SendAfter(method string, seconds int32, msg interface{}) {time.AfterFunc(time.Duration(seconds) * time.Second, func() {if !p.stop {p.reqCh <- GenReq{Method: method, MsgData: msg, t: timer, time:seconds}}}) }func (p *PidObj) Stop() {p.reqCh <- GenReq{t: shutdown} }

  

?

定義接口:

package global// GenServer behavior needs to implement this interface type GenServer interface {Start()HandleCall(GenReq) ReplyHandleCast(GenReq)HandleInfo(GenReq)Stop() }

  

上面是用go實現了類似erlang的gen_server功能,使用的時候只需要實現Start, HandleCall,HandleCast,HandleInfo和Stop

這五個接口就可以了。

ok,that's all !

轉載于:https://www.cnblogs.com/huangliang-hb/p/9640408.html

總結

以上是生活随笔為你收集整理的使用go来实现类似erlang otp里面的gen_server功能的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。