golang中math.rand函数的一个坑

本文探讨了在 Go 语言中使用 math/rand 函数时遇到的一个问题,即相同的随机种子会导致相同的随机数序列。文章分析了 rand 中的全局变量 globalRand 和并发安全问题,指出多个 goroutine 访问 globalRand 时,虽然初始随机种子相同,但后续生成的随机数并不相同,因为它们依赖于之前生成的随机数。此外,文章还提到在并发环境中,fmt.Println 的输出是线程安全的,可能导致选举过程的时间错开,从而避免冲突。通过实验和代码调整,作者揭示了打印日志如何无意中解决了原本的并发问题。
摘要由CSDN通过智能技术生成

        在做raft 2A实验时,遇到一个奇怪的bug,经常会选不出leader,然后想打印日志查看原因发现又能够选出来了,进入了出问题我想看日志,看日志又没问题的奇怪循环中。后来在过整个代码时发现在我重启选举计时器时,又重置了随机种子,而我把这个删去只在初始化过程中重置一次的随机种子,发现整个流程就跑通了。后来查询资料寻找原因主要原因是以下几点:

  1. go中的rand函数是一个伪随机生成,如果随机种子相同那么生成的随机数是一样的。
  2. math.rand提供一个全局的globalRand变量,多个goroutine调用rand()函数时访问的是同一个globarand。(为了并发安全,go还用了一把互斥锁来访问这个globalrand,所以如果将原本单goroutine使用rand改为多线程并发使用rand,可能会因为竞争锁导致性能下降。参考博客)</
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值