mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-04 21:02:27 +08:00
Compare commits
1 Commits
main
...
88cf1600e8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88cf1600e8 |
@@ -10,7 +10,7 @@ import (
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
@@ -27,7 +27,14 @@ const (
|
||||
AllChars = Numeral + LowwerLetters + UpperLetters + SymbolChars
|
||||
)
|
||||
|
||||
var rn = rand.NewSource(time.Now().UnixNano())
|
||||
// var rn = rand.NewSource(time.Now().UnixNano())
|
||||
|
||||
// 每个 goroutine 独立的 rand.Rand,避免并发问题
|
||||
var randPool = sync.Pool{
|
||||
New: func() any {
|
||||
return rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
@@ -286,10 +293,9 @@ func nearestPowerOfTwo(cap int) int {
|
||||
|
||||
// random generate a random string based on given string range.
|
||||
func random(s string, length int) string {
|
||||
// 确保随机数生成器的种子是动态的
|
||||
pid := os.Getpid()
|
||||
timestamp := time.Now().UnixNano()
|
||||
rand.Seed(int64(pid) + timestamp)
|
||||
// 从 pool 中获取 rand.Rand(替代全局 rand)
|
||||
rn := randPool.Get().(*rand.Rand)
|
||||
defer randPool.Put(rn)
|
||||
|
||||
// 仿照strings.Builder
|
||||
// 创建一个长度为 length 的字节切片
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
@@ -376,3 +377,31 @@ func TestRandNumberOfLength(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestRandNumberOfLength")
|
||||
assert.Equal(6, len(strconv.Itoa(randi)))
|
||||
}
|
||||
|
||||
// TestRandStringConcurrent verifies RandString is safe under high concurrency.
|
||||
// Before the fix, this test may panic or trigger data races.
|
||||
// After the fix, it should always pass.
|
||||
func TestRandStringConcurrent(t *testing.T) {
|
||||
const (
|
||||
goroutines = 100
|
||||
iterations = 1000
|
||||
length = 32
|
||||
)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(goroutines)
|
||||
|
||||
for g := 0; g < goroutines; g++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for i := 0; i < iterations; i++ {
|
||||
s := RandString(length)
|
||||
if len(s) != length {
|
||||
t.Fatalf("unexpected string length: got %d, want %d", len(s), length)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user