使用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功能相关推荐
- erlang r19里面的mnesia_ext
r19据说支持了mnesia_ext,终于可以给那个恶心2gb limit的mnesia换存储引擎了 先下载r19源码,编译 ./otp_build all -a ~/dev/erlang/r19 . ...
- sql server2016里面的json功能 - 转
测试一下基本的,从查询结果里面构造一个json 的格式 create table t1(ID int identity,name nvarchar(50),Chinese int ,Math int) ...
- Cocos Creator 如何实现类似王者荣耀里积分夺宝抽奖功能!
● 效果预览 ● 操作方法 输入框内输入需要中的奖品,方位是 [1,8],如果需要抽中多个,数字以 / 分割,如上图效果图示例一样. ● UI布局 ui很简单,三部分组成:奖品列表.输入结果.开始按钮 ...
- 继续说一下2016里面的json功能(1)
首先先来测试数据,数据是使用之前的,就 不要在意这些细节了啊~ 借用上一篇的测试数据 create table t1(ID int identity,name nvarchar(50),Chinese ...
- 用c语言 简单实现JAVA里面的ArryList 功能,实现内存自动扩展
#include<stdio.h> #include<stdlib.h> struct Arr{ int * pbase;//数组首地址 int len;//数 ...
- 《Quaternion》自己实现Quaternion里面的FromToRotation功能
先看代码. /// <summary>/// Handles smaller values better than Unity's version./// </summary> ...
- Erlang/OTP设计原则(文档翻译)
http://erlang.org/doc/design_principles/des_princ.html 图和代码皆源自以上链接中Erlang官方文档,翻译时的版本为20.1. 这个设计原则,其实 ...
- 【Erlang/OTP入门】基于进程的并发编程和分布式
引言 在参加区统考的前一天开始写这篇文章,开学后时间真的紧迫了很多. 我最近玩Erlang只是一个偶然(?).这一切的开始是我某天看到一本名为<Erlang and OTP in Actio ...
- Erlang/OTP:基于Behaviour的回调函数
原始链接:https://blog.zhustec.me/posts/erlang-otp-1-callback-based-on-behaviour OTP 是什么 OTP 的全称是开源电信平台 ( ...
最新文章
- ​西湖大学EMBLab诚聘环境工程学、生物信息学、分子生态学科研助理
- 分享Silverlight新鲜事(11月15日-21日) - PDC 10 Downloader
- JVM源码分析之System.currentTimeMillis及nanoTime原理详解
- mysql全文索引含义_【分针网】MySQL全文索引应用简明教程
- python处理实例_python处理xml实例
- 一键安装mysql5.6_一键安装MySQL5.6.43脚本
- 根据MAC地址修改固定IP(附带IPMAC扫描脚本)
- 尚硅谷设计模式笔记-装饰者模式
- [BZOJ4484][JSOI2015]最小表示(拓扑排序+bitset)
- C++链接和运行相关错误
- 《算法竞赛进阶指南》0.1位运算
- 【推荐系统】音乐推荐系统02
- VS+Qt应用开发-设置鼠标光标
- 《老路用得上的商学课》21-25学习笔记
- 终端数据防泄漏解决方案
- 根据经纬度信息画实际地图中的轨迹之百度地图与谷歌地球
- 数控加工插补功能指令
- [从头读历史] 第278节 诗经 曹风
- android 开发 超级群
- iphone怎么恢复备忘录
热门文章
- strstr函数_[LeetCode] 28. 实现strStr()
- Java字符串编码转换UTF-8
- python 按键精灵 离线_python,PyAutoGUI,自动操作鼠标键盘,类似按键精灵
- mysql提权_mysql提权总结
- 卸载mongodb_【数据库】mongodb数据库安装
- 广东轻工计算机多媒体,广东轻工职业技术学院2015年自主招生计算机多媒体技术专业考核大纲...
- 大橙子_一颗橙子多甜多大,想要甜的还是酸的 您说了算
- linux系统安装金蝶_linux 操作系统安装配置vnc
- linux内核之旅ppt_一起玩转 Linux 内核之旅开源社区吧
- mysql linux centos7_MySQL在Linux centos7环境下安装教程详解(图)