Golang rand.Rand 并发panic: index out of range

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

内容简介:线上服务Panic,部分日志如下放狗搜了一下:math.Rand is not safe for concurrent usefrom:

线上服务Panic,部分日志如下

引用

err: runtime error: index out of range

Traceback:

goroutine 19209941 [running]:

...

panic(0x191d0e0, 0x2e078d0)

/usr/local/go/src/runtime/panic.go:502 +0x229

math/rand.(*rngSource).Uint64(...)

/usr/local/go/src/math/rand/rng.go:246

math/rand.(*rngSource).Int63(0xc438bb2a00, 0x0)

/usr/local/go/src/math/rand/rng.go:231 +0x8a

math/rand.(*Rand).Int63(0xc4279b3a70, 0x0)

/usr/local/go/src/math/rand/rand.go:82 +0x33

math/rand.(*Rand).Int(0xc4279b3a70, 0x0)

/usr/local/go/src/math/rand/rand.go:100 +0x2b

...

放狗搜了一下:math.Rand is not safe for concurrent use

from: https://github.com/golang/go/issues/3611

这个 issue 的 4 楼还提到 "top-level functions like strings.Split or fmt.Printf or rand.Int63 may be called from any goroutine at any time"

翻了一下源码,rand.Int() 用是自带 lock 的 globalRand 对象

func Int() int { return globalRand.Int() }

...

var globalRand = New(&lockedSource{src: NewSource(1).(Source64)})

...

type lockedSource struct {
  lk  sync.Mutex
  src Source64
}

...

func (r *lockedSource) Uint64() (n uint64) {
  r.lk.Lock()
  n = r.src.Uint64()
  r.lk.Unlock()
  return
}

看了下调用代码,之前的实现为了避免多个 goroutine 竞争同一个锁,所以 new 了一个 rand.Rand 对象,但没考虑到这个对象不支持并发。

最终的解决方案,是实现了一个 safeRander 。

具体代码不适合贴,核心逻辑是初始化 N 个 rand.Rand 对象和对应的 N 个锁,以及一个 index,每次调用 Int() 时,先 atomic.AddUint32(&index, 1) % N,加上对应的锁,再用对应的 rand.Rand 对象。

这样只要并发使用的goroutine不超过N个,就不会出现竞争;就算超过,竞争出现的频率也大幅减少了,而且也可以通过增加 N 来优化。

转载请注明出自,如是转载文则注明原出处,谢谢:)

RSS订阅地址: http://www.felix021.com/blog/feed.php


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

查看所有标签

猜你喜欢:

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

社会工程

社会工程

海德纳吉 (Christopher Hadnagy) / 陆道宏、杜娟、邱璟 / 人民邮电出版社 / 2013-12 / 59.00元

本书首次从技术层面剖析和解密社会工程手法,从攻击者的视角详细介绍了社会工程的所有方面,包括诱导、伪装、心理影响和人际操纵等,并通过凯文 · 米特尼克等社会工程大师的真实故事和案例加以阐释,探讨了社会工程的奥秘。主要内容包括黑客、间谍和骗子所使用的欺骗手法,以及防止社会工程威胁的关键步骤。 本书适用于社会工程师、对社会工程及信息安全感兴趣的人。一起来看看 《社会工程》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具