mirror of
https://github.com/charlienet/go-mixed.git
synced 2025-07-18 00:22:41 +08:00
update
This commit is contained in:
17
compiled_buffer/regex2_test.go
Normal file
17
compiled_buffer/regex2_test.go
Normal 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"))
|
||||
}
|
@ -7,6 +7,7 @@ import (
|
||||
const (
|
||||
layoutDate = "2006-01-02"
|
||||
layoutTime = "2006-01-02 15:04:05"
|
||||
layoutTimeMilli = "2006-01-02 15:04:05.000"
|
||||
layoutChineseDate = "2006年01月02日"
|
||||
layoutChineseTime = "2006年01月02日 15:04:05"
|
||||
)
|
||||
|
41
locker/chan_source_locker.go
Normal file
41
locker/chan_source_locker.go
Normal 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()
|
||||
}
|
@ -2,53 +2,93 @@ package locker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// 带计数器锁
|
||||
type countLocker struct {
|
||||
Locker
|
||||
Count int32
|
||||
}
|
||||
|
||||
// 资源锁
|
||||
type SourceLocker struct {
|
||||
m RWLocker
|
||||
locks map[string]Locker
|
||||
locks map[string]*countLocker
|
||||
}
|
||||
|
||||
func NewSourceLocker() *SourceLocker {
|
||||
return &SourceLocker{
|
||||
m: NewRWLocker(),
|
||||
locks: make(map[string]Locker),
|
||||
locks: make(map[string]*countLocker),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SourceLocker) Lock(key string) {
|
||||
s.m.RLock()
|
||||
l, ok := s.locks[key]
|
||||
s.m.RUnlock()
|
||||
|
||||
if ok {
|
||||
s.m.RUnlock()
|
||||
|
||||
atomic.AddInt32(&l.Count, 1)
|
||||
l.Lock()
|
||||
|
||||
fmt.Println("加锁")
|
||||
} else {
|
||||
s.m.RUnlock()
|
||||
|
||||
// 加锁,再次检查是否已经具有锁
|
||||
s.m.Lock()
|
||||
new := NewLocker()
|
||||
s.locks[key] = new
|
||||
if l2, ok := s.locks[key]; ok {
|
||||
s.m.Unlock()
|
||||
|
||||
l2.Lock()
|
||||
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) {
|
||||
s.m.Lock()
|
||||
|
||||
if l, ok := s.locks[key]; ok {
|
||||
atomic.AddInt32(&l.Count, -1)
|
||||
fmt.Printf("解锁%p\n", l)
|
||||
l.Unlock()
|
||||
// delete(s.locks, key)
|
||||
fmt.Println("解锁")
|
||||
|
||||
if l.Count == 0 {
|
||||
delete(s.locks, key)
|
||||
}
|
||||
}
|
||||
s.m.Unlock()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,15 @@ package locker
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var sourcekey = "u-0001"
|
||||
|
||||
func TestTryLock(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestSourceLocker(t *testing.T) {
|
||||
l := NewSourceLocker()
|
||||
|
||||
@ -27,6 +32,32 @@ func TestSourceLocker(t *testing.T) {
|
||||
|
||||
wg.Wait()
|
||||
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) {
|
||||
|
Reference in New Issue
Block a user