• Go语言开发中遇到的一个问题:RandString(32)返回的全是 0
  • 发布于 1周前
  • 39 热度
    1 评论
  • 冰魄
  • 0 粉丝 39 篇博客
  •   
下面这段代码在长时间运行后,有一定的机率会出错,RandString(32)返回的全是 0.从网上查的资料全局变量应该不会被回收才对。
package helper

import (
"math/rand"
"time"
)

const _charsetRand = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$"

var _seededRand = rand.New(rand.NewSource(time.Now().UnixNano()))

// RandStringWithCharset rand string with charset
func RandStringWithCharset(length int, charset string) string {
b := make([]byte, length)
l := len(charset)
for i := range b {
b[i] = charset[_seededRand.Intn(l)]
}
return string(b)
}

// RandString rand string
func RandString(length int) string {
return RandStringWithCharset(length, _charsetRand)
}

// RandInt rand int between [min, max)
func RandInt(min int, max int) int {
if min <= 0 || max <= 0 {
return 0
}

if min >= max {
return max
}

return _seededRand.Intn(max-min) + min
}

// RandMax rand int between [0, max)
func RandMax(max int) int {
if max <= 1 {
return 0
}

return _seededRand.Intn(max)
}
大家帮忙看一下,这是哪里出现问题了?
用户评论
  • 我没那么帅
  • 这段代码的问题在于并发访问了全局的 _seededRand 变量,导致了竞争条件( race condition )。在多个 goroutine 同时调用 RandStringWithCharset 函数时,它们可能会同时访问和修改 _seededRand ,从而导致不可预测的结果,甚至造成程序崩溃。

    在第一段代码中,_seededRand 被多个 goroutine 同时访问和修改,因为没有对其进行同步操作或者使用互斥锁。而在第二段代码中,通过在 RandStringWithCharset 函数中调用 createRand 函数,每次都创建一个新的 _seededRand 实例,避免了并发访问全局变量的问题。通过这样的修改,确保了在并发情况下每个 goroutine 都有自己的 _seededRand 实例,从而解决了竞争条件问题,确保了程序的稳定性。
  • 2024/5/8 12:14:00 [ 0 ] [ 0 ] 回复