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功能相关推荐

  1. erlang r19里面的mnesia_ext

    r19据说支持了mnesia_ext,终于可以给那个恶心2gb limit的mnesia换存储引擎了 先下载r19源码,编译 ./otp_build all -a ~/dev/erlang/r19 . ...

  2. sql server2016里面的json功能 - 转

    测试一下基本的,从查询结果里面构造一个json 的格式 create table t1(ID int identity,name nvarchar(50),Chinese int ,Math int) ...

  3. Cocos Creator 如何实现类似王者荣耀里积分夺宝抽奖功能!

    ● 效果预览 ● 操作方法 输入框内输入需要中的奖品,方位是 [1,8],如果需要抽中多个,数字以 / 分割,如上图效果图示例一样. ● UI布局 ui很简单,三部分组成:奖品列表.输入结果.开始按钮 ...

  4. 继续说一下2016里面的json功能(1)

    首先先来测试数据,数据是使用之前的,就 不要在意这些细节了啊~ 借用上一篇的测试数据 create table t1(ID int identity,name nvarchar(50),Chinese ...

  5. 用c语言 简单实现JAVA里面的ArryList 功能,实现内存自动扩展

    #include<stdio.h> #include<stdlib.h> struct Arr{     int * pbase;//数组首地址     int len;//数 ...

  6. 《Quaternion》自己实现Quaternion里面的FromToRotation功能

    先看代码. /// <summary>/// Handles smaller values better than Unity's version./// </summary> ...

  7. Erlang/OTP设计原则(文档翻译)

    http://erlang.org/doc/design_principles/des_princ.html 图和代码皆源自以上链接中Erlang官方文档,翻译时的版本为20.1. 这个设计原则,其实 ...

  8. 【Erlang/OTP入门】基于进程的并发编程和分布式

    引言 在参加区统考的前一天开始写这篇文章,开学后时间真的紧迫了很多.   我最近玩Erlang只是一个偶然(?).这一切的开始是我某天看到一本名为<Erlang and OTP in Actio ...

  9. Erlang/OTP:基于Behaviour的回调函数

    原始链接:https://blog.zhustec.me/posts/erlang-otp-1-callback-based-on-behaviour OTP 是什么 OTP 的全称是开源电信平台 ( ...

最新文章

  1. ​西湖大学EMBLab诚聘环境工程学、生物信息学、分子生态学科研助理
  2. 分享Silverlight新鲜事(11月15日-21日) - PDC 10 Downloader
  3. JVM源码分析之System.currentTimeMillis及nanoTime原理详解
  4. mysql全文索引含义_【分针网】MySQL全文索引应用简明教程
  5. python处理实例_python处理xml实例
  6. 一键安装mysql5.6_一键安装MySQL5.6.43脚本
  7. 根据MAC地址修改固定IP(附带IPMAC扫描脚本)
  8. 尚硅谷设计模式笔记-装饰者模式
  9. [BZOJ4484][JSOI2015]最小表示(拓扑排序+bitset)
  10. C++链接和运行相关错误
  11. 《算法竞赛进阶指南》0.1位运算
  12. 【推荐系统】音乐推荐系统02
  13. VS+Qt应用开发-设置鼠标光标
  14. 《老路用得上的商学课》21-25学习笔记
  15. 终端数据防泄漏解决方案
  16. 根据经纬度信息画实际地图中的轨迹之百度地图与谷歌地球
  17. 数控加工插补功能指令
  18. [从头读历史] 第278节 诗经 曹风
  19. android 开发 超级群
  20. iphone怎么恢复备忘录

热门文章

  1. strstr函数_[LeetCode] 28. 实现strStr()
  2. Java字符串编码转换UTF-8
  3. python 按键精灵 离线_python,PyAutoGUI,自动操作鼠标键盘,类似按键精灵
  4. mysql提权_mysql提权总结
  5. 卸载mongodb_【数据库】mongodb数据库安装
  6. 广东轻工计算机多媒体,广东轻工职业技术学院2015年自主招生计算机多媒体技术专业考核大纲...
  7. 大橙子_一颗橙子多甜多大,想要甜的还是酸的 您说了算
  8. linux系统安装金蝶_linux 操作系统安装配置vnc
  9. linux内核之旅ppt_一起玩转 Linux 内核之旅开源社区吧
  10. mysql linux centos7_MySQL在Linux centos7环境下安装教程详解(图)