博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Go标准库plugin源码分析----动态库使用
阅读量:4030 次
发布时间:2019-05-24

本文共 1499 字,大约阅读时间需要 4 分钟。

本文公众号文章链接:

 

 

 

Go通常都是编译打包成一个可执行文件,好处是不需要考虑依赖库,一个可执行文件,拷贝就可以直接执行。

但还有些场景,如需要以插件形式加载,方便动态更新,热重启等情况。这些场景的需求,就带来了plugin库,动态库加载。

 

那么先看看plguin这个库的文档。文档为1.10版本

 

编译命令和普通的编译不一样,增加了参数-buildmode=plugin

 

另外plugin第一次加载时候,init函数会调用。(后面的源码分析中会分析)

注意:

1、plugin只init一次,并且不能closed。

2、目前只实现了linux平台和macos平台

 

 

文件很少,就只有两个(其实源码里有三个文件)

只提供了两个接口

Open:加载so库文件

Lookup:查找对应符号(包括func,var等)

 

文档中的示例

 

其中值得注意的是package是main

 

两个接口的使用,Open加载库文件,Lookup查找符号

示例中,有一个var,有一个func

 

那么再看下例子

 

 

这个里面多了一个init

使用

 

 

 

好了,下面看源码

 

源码目录

 

src/plugin/plugin.go

 

pluginpath:库的path

err:用于记录过程中的err

loaded:这个用于防止并发加载同一个库时候用

syms:这个记录的是库中所有的符号和其对应的值(可能是var、func等)

 

 

Open函数,封装了open函数

 

Lookup函数封装了lookup函数

 

src/plugin/plugin_stubs.go

 

这里是针对不支持平台的空实现,!linux,!darwin !cgo。可以看出,和文档中说的一样,非Linux,非darwin平台的时候编译成空实现。当然还有一个cgo,如果不支持cgo的话,也是无法实现plugin的。

 

那么看最后一个文件

src/plugin/plugin_dlopen.go

 

编译命令中,显示支持linux 和 darwin平台,当然要求是要支持cgo。

然后就是一个cgo的代码。其中封装了两个函数dlopen,dlsym。

其实看到这两个函数,就应该很熟悉了。

 

这个是linux种标准的动态链接加载接口。

 

当然plugin只实现了封装了dlopen,dlsym,两个函数。这个和文档中所提供的接口和描述是符合的。

只提供了加载,并没有提供关闭。

 

继续看源码

 

全局变量

pluginsMu:全局锁

plugins:保存加载的动态库

 

open

 

进入函数,一开始是一些字符串的转换。

重点是加锁后,会判断是否已经在加载,或者已经加载过的plugin。

这个时候,如果刚好plugin还在加载中,

<- p.loaded 会等待plugin加载完毕后,close掉p.loaded。

这种方式就是合并加载

 

 

这里就是调用了cgo代码pluginOpen,加载so库

 

初始化plugin结构体,并将其放入到全局的plugins这个map中。然后unlock全局锁。

继续,调用了cgo代码pluginLookup,查找init函数,并执行。

 

 

接着就是循环读取所有的符号,并将符号与其对应的值保存下来。保存在p.syms中。

最后close p.loaded,表示加载过程结束了。

 

lookup

 

所有的符号都保存在p.syms中,这个时候的查找,就只需要直接查找syms就可以了。

 

 

龚浩华

月牙寂道长

QQ 29185807

2018年04月16日

如果你觉得本文对你有帮助,可以转发分享到你的朋友圈,让更多人一起学习。

第一时间获取文章,可以关注本人公众号:月牙寂道长,也可以扫码关注

你可能感兴趣的文章
自然计算时间复杂度杂谈
查看>>
当前主要目标和工作
查看>>
系统菜单
查看>>
路漫漫其修远兮,吾将上下而求索(2)
查看>>
versions mac yosemite 下崩溃的修复
查看>>
github push 出现connection refused 的处理办法
查看>>
Linux配置sendmail实现PHP发送邮件
查看>>
c++ 特性回顾
查看>>
网站注册的时候,烦人的生日年份选择的改进想法
查看>>
游戏开发两年记 之 工程和理论需双剑合璧
查看>>
Nachos中switch汇编源码分析
查看>>
游戏开发两年之产品逻辑鸡肋么?
查看>>
secureCRT和Xshell登录Ubuntu
查看>>
secureCRT和Xshell登录ubuntu
查看>>
Apache下c语言的cgi如何获得Get,Post参数
查看>>
protobuf的使用初探
查看>>
ngx_http分析
查看>>
搭建一个php学习框架mycake
查看>>
MVC模式概念
查看>>
大量拉取网络数据的策略总结
查看>>