Goroutine的上下文存储(续)

栏目: Go · 发布时间: 6年前

内容简介:要做Goroutine级别的存储,首先是要获取到Goroutine的标识,之前提到过获取routine id的两个库,效率也比较低下,用在性能要求比较苛刻的场景下并不适合。最近看到有个通过go汇编获取goid的方法,获取到goid以后,我们就可以通过map来存储上下文了。

要做Goroutine级别的存储,首先是要获取到Goroutine的标识,之前提到过获取routine id的两个库,效率也比较低下,用在性能要求比较苛刻的场景下并不适合。

最近看到有个通过 go 汇编获取goid的方法, https://chai2010.cn/advanced-go-programming-book/ch3-asm/ch3-08-goroutine-id.html 。原理其实很简单,golang的内部其实是存储了routineid的,放在了runtime2.go文件的g struct中,只不过这个struct是私有变量,不可以通过外部访问。通过go汇编,我们可以绕过go语言层级带来的障碍,直接访问到对象所在的内存。

获取到goid以后,我们就可以通过map来存储上下文了。

新的问题是,golang的map并不是线程安全,并发的读写会产生问题。实现过程中需要考虑多线程的安全问题。原文提供的方案比较简单,就是在读写过程中对map加互斥锁。进一步的优化方案是使用RWMutex,读map的时候加RLock,写操作加互斥锁,这个也是golang官方推荐的方案, https://blog.golang.org/go-maps-in-action

golang的sync包下面,也有一套map的同步方案,sync/map.go,那么这个方法又有什么特点,我们该怎么选择呢?看了源码以后,发现这一套方案主要是通过空间换时间的方法来减少锁的使用,内部通过两个map存储数据,老的数据存放在read map,新数据存放dirty map,如果数据特征是一次写入,多次读出,那么多数的读请求都会落入read map,不需要加锁,从而提升并发性能。

那么,实际过程中,这三种方案的性能表现到底如何呢?我对不同的读写比例和不同的并发程度做了benchmark,详情见下图。直接上结论,在读写比例100:1以下时RWMutex方案有绝对优势,更高的读写比例下,sync.Map的方案具有更高的性能;RWMutex和sync.Map的性能在大部分情况下都比单锁的方案高,并发程度越高,优势越明显。

Goroutine的上下文存储(续)

10次读操作

Goroutine的上下文存储(续)

100次读操作

Goroutine的上下文存储(续)

1000次读操作

回到我们的场景,上下文存储经常用来处理http server请求相关的数据,减少层层传参。这种场景下,读写比例不会非常高,所以一般来说RWMutex方案是最优的选择。

实现代码和bechmark代码见github, https://github.com/JasonYuan/gls.git

另,在看sync.Map的过程中,顺便看了下sync.atomic,顾名思义,这是保证各种数据操作原子性的的库。看到一个有意思的事情,在amd64下,大部分的内置类型实际上都可以保证写入的原子性,但是interface类型是不能保证的,原因是interface的内部存储是个struct,同时保存了类型和地址。这时候可以通过atomic.Value来实现,实现过程无锁,可以放心服用。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JSP 应用开发详解(第二版)

JSP 应用开发详解(第二版)

飞思科技产品研发中心 / 电子工业出版社 / 2004-1-1 / 55.00

本书结合JSP和Servlet的最新规范,从基本的语法和规范入手,以经验为后盾,以实用为目标,以实例为导向,以实践为指导,深入浅出地讲解了JSP 开发中的种种问题。以精简的内容介绍了JSP的语法、Servlet技术、JDBC技术、标签库技术、表达式语言、Struts、JavaServer Face等技术;对于JSP开发中常遇到的典型的难点,专门设置了专题进行集中讨论。本书的最后一篇围绕一个电子商务......一起来看看 《JSP 应用开发详解(第二版)》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具