From 72952dc746e3861d60dff2292377872c9d03d2ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 14 May 2022 15:59:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=90=AC=E8=BF=81easy=20lock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 22 ++++++++++++ abstruct.go | 26 ++++++++++++++ define.go | 92 +++++++++++++++++++++++++++++++++++++++++++++++++ error.go | 19 ++++++++++ go.mod | 13 +++++++ go.sum | 10 ++++++ lock.go | 59 +++++++++++++++++++++++++++++++ lock_segment.go | 68 ++++++++++++++++++++++++++++++++++++ 8 files changed, 309 insertions(+) create mode 100644 .gitignore create mode 100644 abstruct.go create mode 100644 define.go create mode 100644 error.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 lock.go create mode 100644 lock_segment.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..df8e306 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Created by .ignore support plugin (hsz.mobi) +### Go template +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +*.xlsx + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ +.idea +.vscode +mail_test.go + diff --git a/abstruct.go b/abstruct.go new file mode 100644 index 0000000..fba1523 --- /dev/null +++ b/abstruct.go @@ -0,0 +1,26 @@ +// Package easylock ... +// +// Description : easylock ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-02-24 6:29 下午 +package easylock + +// EasyLock ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:18 下午 2021/4/1 +type EasyLock interface { + // Lock ... + Lock(optionFuncList ...OptionFunc) error + // Unlock ... + Unlock(optionFuncList ...OptionFunc) error + // RLock ... + RLock(optionFuncList ...OptionFunc) error + // RUnlock ... + RUnlock(optionFuncList ...OptionFunc) error + // GetLockCnt 获取锁总数 + GetLockCnt() *LockCnt +} diff --git a/define.go b/define.go new file mode 100644 index 0000000..4f9578c --- /dev/null +++ b/define.go @@ -0,0 +1,92 @@ +// Package easylock ... +// +// Description : easylock ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-04-01 4:13 下午 +package easylock + +type option struct { + flag string // 锁的标识 +} + +// OptionFunc 设置option选项 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:15 下午 2021/4/1 +type OptionFunc func(o *option) + +// WithFlag 设置flag +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:17 下午 2021/4/1 +func WithFlag(flag string) OptionFunc { + return func(o *option) { + o.flag = flag + } +} + +// LockCnt 计数lockCnt +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:41 下午 2021/4/1 +type LockCnt struct { + Write int64 `json:"write"` + Read int64 `json:"read"` +} + +type base struct { +} + +// ParseOption 解析option +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:24 下午 2021/4/1 +func (b *base) ParseOption(optionFuncList ...OptionFunc) *option { + o := &option{} + for _, f := range optionFuncList { + f(o) + } + return o +} + +// AddLockCnt 锁数量加一 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:44 下午 2021/4/1 +func (b *base) AddLockCnt(lockCnt *LockCnt) { + lockCnt.Write++ +} + +// DecreaseLockCnt 锁数量 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:45 下午 2021/4/1 +func (b *base) DecreaseLockCnt(lockCnt *LockCnt) { + lockCnt.Write-- +} + +// AddRLockCnt 锁数量加一 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:44 下午 2021/4/1 +func (b *base) AddRLockCnt(lockCnt *LockCnt) { + lockCnt.Read++ +} + +// DecreaseRLockCnt 锁数量 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:45 下午 2021/4/1 +func (b *base) DecreaseRLockCnt(lockCnt *LockCnt) { + lockCnt.Read-- +} diff --git a/error.go b/error.go new file mode 100644 index 0000000..a0fb72f --- /dev/null +++ b/error.go @@ -0,0 +1,19 @@ +// Package easylock ... +// +// Description : easylock ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-02-24 10:55 下午 +package easylock + +import "github.com/pkg/errors" + +// segmentError ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 1:44 下午 2021/2/24 +func segmentError() error { + return errors.New("segment需要大于0") +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7e98590 --- /dev/null +++ b/go.mod @@ -0,0 +1,13 @@ +module easylock + +go 1.17 + +require ( + git.zhangdeman.cn/zhangdeman/util v0.0.0-20220514075609-25936d457a72 + github.com/pkg/errors v0.9.1 +) + +require ( + github.com/spaolacci/murmur3 v1.1.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d1bee5a --- /dev/null +++ b/go.sum @@ -0,0 +1,10 @@ +git.zhangdeman.cn/zhangdeman/util v0.0.0-20220514075609-25936d457a72 h1:kPx8DFXmsyBeEiLjolzG8ZlIGYUhBbTWcn65AuMGLy8= +git.zhangdeman.cn/zhangdeman/util v0.0.0-20220514075609-25936d457a72/go.mod h1:YI/XeTmrr9+8dxa4ThPkmNcEE8WHG5pZkKujpSWwIxM= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/lock.go b/lock.go new file mode 100644 index 0000000..d79552e --- /dev/null +++ b/lock.go @@ -0,0 +1,59 @@ +// Package easylock ... +// +// Description : 包装各种姿势的锁 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-02-24 6:26 下午 +package easylock + +import "sync" + +// NewLock 获取普通锁实例,因为只有一把锁,flag没有意义,传空即可 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 10:42 下午 2021/2/24 +func NewLock() EasyLock { + return &lock{ + sc: &sync.RWMutex{}, + lockCnt: &LockCnt{ + Write: 0, + Read: 0, + }, + } +} + +type lock struct { + sc *sync.RWMutex + lockCnt *LockCnt + base +} + +func (l *lock) Lock(optionFuncList ...OptionFunc) error { + defer l.AddLockCnt(l.lockCnt) + l.sc.Lock() + return nil +} + +func (l *lock) Unlock(optionFuncList ...OptionFunc) error { + defer l.DecreaseLockCnt(l.lockCnt) + l.sc.Unlock() + return nil +} + +func (l *lock) RLock(optionFuncList ...OptionFunc) error { + defer l.AddRLockCnt(l.lockCnt) + l.sc.RLock() + return nil +} + +func (l *lock) RUnlock(optionFuncList ...OptionFunc) error { + defer l.DecreaseRLockCnt(l.lockCnt) + l.sc.RUnlock() + return nil +} + +func (l *lock) GetLockCnt() *LockCnt { + return l.lockCnt +} diff --git a/lock_segment.go b/lock_segment.go new file mode 100644 index 0000000..6228848 --- /dev/null +++ b/lock_segment.go @@ -0,0 +1,68 @@ +// Package easylock ... +// +// Description : 分段的锁 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-02-24 10:44 下午 +package easylock + +import "git.zhangdeman.cn/zhangdeman/util" + +// NewSegment 获取分段锁 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 11:20 下午 2021/2/24 +func NewSegment(segmentCnt int) (EasyLock, error) { + if segmentCnt <= 0 { + return nil, segmentError() + } + s := &segment{ + lockTable: make([]EasyLock, segmentCnt), + segmentCnt: segmentCnt, + lockCnt: &LockCnt{ + Write: 0, + Read: 0, + }, + } + for i := 0; i < segmentCnt; i++ { + s.lockTable[i] = NewLock() + } + return s, nil +} + +type segment struct { + lockTable []EasyLock + segmentCnt int + lockCnt *LockCnt + base +} + +func (s *segment) Lock(optionFuncList ...OptionFunc) error { + defer s.AddRLockCnt(s.lockCnt) + o := s.ParseOption(optionFuncList...) + return s.lockTable[util.Hash.GetHashIDMod(o.flag, s.segmentCnt)].Lock() +} + +func (s *segment) Unlock(optionFuncList ...OptionFunc) error { + defer s.DecreaseLockCnt(s.lockCnt) + o := s.ParseOption(optionFuncList...) + return s.lockTable[util.Hash.GetHashIDMod(o.flag, s.segmentCnt)].Unlock() +} + +func (s *segment) RLock(optionFuncList ...OptionFunc) error { + defer s.AddRLockCnt(s.lockCnt) + o := s.ParseOption(optionFuncList...) + return s.lockTable[util.Hash.GetHashIDMod(o.flag, s.segmentCnt)].RLock() +} + +func (s *segment) RUnlock(optionFuncList ...OptionFunc) error { + defer s.DecreaseRLockCnt(s.lockCnt) + o := s.ParseOption(optionFuncList...) + return s.lockTable[util.Hash.GetHashIDMod(o.flag, s.segmentCnt)].RUnlock() +} + +func (s *segment) GetLockCnt() *LockCnt { + return s.lockCnt +}