1
0
mirror of https://github.com/charlienet/go-mixed.git synced 2025-07-18 00:22:41 +08:00
This commit is contained in:
2022-07-26 14:19:40 +08:00
parent 23865214c8
commit 792458a185
5 changed files with 144 additions and 14 deletions

View File

@ -0,0 +1,17 @@
package compiledbuffer
import (
"testing"
"github.com/dlclark/regexp2"
)
func TestCom(t *testing.T) {
regex, err := regexp2.Compile(`^\d{11}[;](?!(37|38))\d{2}\d{6}$`, regexp2.None)
if err != nil {
t.Fatal(err)
}
t.Log(regex.MatchString("14610522152;37764800"))
t.Log(regex.MatchString("14610522152;33764800"))
}

View File

@ -7,6 +7,7 @@ import (
const ( const (
layoutDate = "2006-01-02" layoutDate = "2006-01-02"
layoutTime = "2006-01-02 15:04:05" layoutTime = "2006-01-02 15:04:05"
layoutTimeMilli = "2006-01-02 15:04:05.000"
layoutChineseDate = "2006年01月02日" layoutChineseDate = "2006年01月02日"
layoutChineseTime = "2006年01月02日 15:04:05" layoutChineseTime = "2006年01月02日 15:04:05"
) )

View File

@ -0,0 +1,41 @@
package locker
type ChanLocker interface {
Get(key string) (ch <-chan int, ok bool)
Release(key string)
}
type chanSourceLock struct {
m RWLocker
content map[string]chan int
}
func (s *chanSourceLock) Get(key string) (ch <-chan int, ok bool) {
s.m.RLock()
ch, ok = s.content[key]
s.m.RUnlock()
if ok {
return
}
s.m.Lock()
ch, ok = s.content[key]
if ok {
s.m.Unlock()
return
}
s.content[key] = make(chan int)
ch = s.content[key]
ok = true
s.m.Unlock()
return
}
func (s *chanSourceLock) Release(key string) {
s.m.Lock()
ch, ok := s.content[key]
if ok {
close(ch)
delete(s.content, key)
}
s.m.Unlock()
}

View File

@ -2,53 +2,93 @@ package locker
import ( import (
"fmt" "fmt"
"sync/atomic"
) )
// 带计数器锁
type countLocker struct {
Locker
Count int32
}
// 资源锁 // 资源锁
type SourceLocker struct { type SourceLocker struct {
m RWLocker m RWLocker
locks map[string]Locker locks map[string]*countLocker
} }
func NewSourceLocker() *SourceLocker { func NewSourceLocker() *SourceLocker {
return &SourceLocker{ return &SourceLocker{
m: NewRWLocker(), m: NewRWLocker(),
locks: make(map[string]Locker), locks: make(map[string]*countLocker),
} }
} }
func (s *SourceLocker) Lock(key string) { func (s *SourceLocker) Lock(key string) {
s.m.RLock() s.m.RLock()
l, ok := s.locks[key] l, ok := s.locks[key]
s.m.RUnlock()
if ok { if ok {
s.m.RUnlock() atomic.AddInt32(&l.Count, 1)
l.Lock() l.Lock()
fmt.Println("加锁") fmt.Println("加锁")
} else { } else {
s.m.RUnlock() // 加锁,再次检查是否已经具有锁
s.m.Lock() s.m.Lock()
new := NewLocker() if l2, ok := s.locks[key]; ok {
s.locks[key] = new s.m.Unlock()
s.m.Unlock()
new.Lock() l2.Lock()
fmt.Println("初始加锁") fmt.Println("二次检查加锁")
} else {
new := NewLocker()
s.locks[key] = &countLocker{Locker: new, Count: 1}
s.m.Unlock()
fmt.Printf("新锁准备加锁:%p\n", new)
new.Lock()
fmt.Println("初始加锁")
}
} }
} }
func (s *SourceLocker) Unlock(key string) { func (s *SourceLocker) Unlock(key string) {
s.m.Lock() s.m.Lock()
if l, ok := s.locks[key]; ok { if l, ok := s.locks[key]; ok {
atomic.AddInt32(&l.Count, -1)
fmt.Printf("解锁%p\n", l)
l.Unlock() l.Unlock()
// delete(s.locks, key)
fmt.Println("解锁") if l.Count == 0 {
delete(s.locks, key)
}
} }
s.m.Unlock() s.m.Unlock()
} }
func (s *SourceLocker) TryLock(key string) bool { func (s *SourceLocker) TryLock(key string) bool {
return false // 加读锁
s.m.RLock()
l, ok := s.locks[key]
if ok {
ret := l.TryLock()
s.m.RUnlock()
return ret
} else {
s.m.RUnlock()
s.m.Lock()
new := NewLocker()
s.locks[key] = &countLocker{Locker: new, Count: 1}
s.m.Unlock()
return new.TryLock()
}
} }

View File

@ -3,10 +3,15 @@ package locker
import ( import (
"sync" "sync"
"testing" "testing"
"time"
) )
var sourcekey = "u-0001" var sourcekey = "u-0001"
func TestTryLock(t *testing.T) {
}
func TestSourceLocker(t *testing.T) { func TestSourceLocker(t *testing.T) {
l := NewSourceLocker() l := NewSourceLocker()
@ -27,6 +32,32 @@ func TestSourceLocker(t *testing.T) {
wg.Wait() wg.Wait()
t.Log("n:", n) t.Log("n:", n)
t.Logf("%+v", l)
}
func TestSourceTryLock(t *testing.T) {
c := 5
n := 0
wg := new(sync.WaitGroup)
wg.Add(c)
l := NewSourceLocker()
for i := 0; i < c; i++ {
go func() {
defer wg.Done()
if l.TryLock(sourcekey) {
n++
time.Sleep(time.Second)
l.Unlock(sourcekey)
}
}()
}
wg.Wait()
t.Log("n:", n)
t.Logf("%+v", l)
} }
func BenchmarkSourceLocker(b *testing.B) { func BenchmarkSourceLocker(b *testing.B) {