關於golang隨機種子的注意點
go語言裡,在併發下,設定隨機數種子的方法(Seed())和隨機數其他方法(比如,Intn())是不能共存的。
背景:之前在一個專案裡需要生成隨機數,上線之後總是報有大量的499超時,程式碼各種優化到沒得優化也找不出問題,哪知最後逐行排查打時間戳,居然是隨機數的原因,隨機數的產生居然需要10來ms。
當時的程式碼產生隨機數是這兩句:
rand.Seed(time.Now().UnixNano())
rnd_int := rand.Intn(11)
後來查原始碼文件有說明:// Seed should not be called concurrently with any other Rand method.
所以以後還是想起他辦法去隨機數吧,比如給時間戳取模之類的、用shuffle()方法洗牌再取之類。
最後,寫了個小程式,可以壓測一下看看效果:
package main
import (
"fmt"
"math/rand"
"net/http"
"strconv"
"sync"
"time"
)
type Demo struct {
rnd *rand.Rand
Lock sync.RWMutex
}
func (d Demo) Get() int {
d.Lock.RLock()
defer d.Lock.RUnlock()
d.rnd.Seed(time.Now().UnixNano())
return d.rnd.Intn(11)
}
func main() {
// 最快
http.HandleFunc("/intn", func(w http.ResponseWriter, r *http.Request) {
t1 := time.Now().UnixNano() / 1e3
rnd_int := rand.Intn(11)
t2 := time.Now().UnixNano() / 1e3
fmt.Println(t2 - t1)
rnd_str := strconv.Itoa(rnd_int)
fmt.Fprintln(w, rnd_str, r.URL.Path)
})
// 不能併發取,會慢
http.HandleFunc("/seed", func(w http.ResponseWriter, r *http.Request) {
t1 := time.Now().UnixNano() / 1e3
rand.Seed(time.Now().UnixNano())
rnd_int := rand.Intn(10-0+1) + 0
t2 := time.Now().UnixNano() / 1e3
fmt.Println(t2 - t1)
rnd_str := strconv.Itoa(rnd_int)
fmt.Fprintln(w, rnd_str, r.URL.Path)
})
// 可以併發取,加了鎖
http.HandleFunc("/seedCon", func(w http.ResponseWriter, r *http.Request) {
t1 := time.Now().UnixNano() / 1e3
rObj := Demo{
rnd : rand.New(rand.NewSource(time.Now().UnixNano())),
}
rnd_int := rObj.Get()
t2 := time.Now().UnixNano() / 1e3
fmt.Println(t2 - t1)
rnd_str := strconv.Itoa(rnd_int)
fmt.Fprintln(w, rnd_str, r.URL.Path)
})
//監聽3000埠
http.ListenAndServe(":3000", nil)
}
wrk -t200 -c200 -d60s "http://127.0.0.1:3000/intn"
wrk -t200 -c200 -d60s "http://127.0.0.1:3000/seed"
wrk -t200 -c200 -d60s "http://127.0.0.1:3000/seedCon"
相關文章
- weblogic 隨機種子Web隨機
- 需要提醒你關於 golang 中 map 使用的幾點注意事項Golang
- 隨機數種子(random seed)隨機random
- matlab 隨機數種子Matlab隨機
- 關於Golang struct{}{}用法和注意事項GolangStruct
- 弱隨機化種子漏洞科普隨機
- C程式隨機種子原始碼C程式隨機原始碼
- unordered_map隨機底數種子隨機
- Golang switch case 的使用注意點Golang
- 關於CORS 應該注意的幾點CORS
- 關於MongoDB的幾點注意事項UMMongoDB
- 關於dispatch_once的坑及注意點
- pytorch---之隨機種子初始化PyTorch隨機
- Golang - 關於 proto 檔案的一點小思考Golang
- 關於C++引用的一些注意點C++
- 關於code::blocks的幾點注意 part1BloC
- golang split需要注意的一個點Golang
- 關於C# 的高效隨機字串 (轉)C#隨機字串
- GoLang 中的隨機數 tipsGolang隨機
- 關於matlab生成隨機數Matlab隨機
- 關於文化課(語文)老師的隨機點學號軟體有感隨機
- 關於dismissViewControllerAnimated值得注意的一點(deinit)ViewController
- 關於golang的goroutine schedulerGolang
- wordpress的save_post鉤子注意點
- 一道關於隨機數生成的題目隨機
- 關於如何產生隨機數的幾種方法彙總!(2018.07.08)隨機
- Golang生成區間隨機整數Golang隨機
- 運用JS 實現隨機點名 (隨機點名)JS隨機
- javascript關於Array()建構函式引數注意點JavaScript函式
- ruby關於flip-flop理解上一個注意點
- 有沒有關於物聯網創新的點子
- 關於golang的time包總結Golang
- 手機網站的幾點注意網站
- Java學習關於隨機數工具類--Random類Java隨機random
- numpy各種生成隨機數的方法隨機
- Java隨機數的幾種有趣用法Java隨機
- 關於網上各種技術文章的一點思考
- jQuery 關於點選選單項,使子條目jQuery