首页 > 其他分享 >Go组件库总结之无等待锁

Go组件库总结之无等待锁

时间:2023-02-26 23:11:07浏览次数:47  
标签:总结 return countGuard 组件 Mutex atomic func time Go

本篇文章我们用Go封装一个无等待锁库。文章参考自:https://github.com/brewlin/net-protocol

1.锁的封装

type Mutex struct {
    v  int32
    ch chan struct{}
}

2.锁的初始化

func (m *Mutex) Init() {
    m.v = 1
    m.ch = make(chan struct{}, 1)
}

3.等待锁

如果没有拿到锁值,将会阻塞在信道上。

func (m *Mutex) Lock() {
    if atomic.AddInt32(&m.v, -1) == 0 {
        return
    }

    for {
        if v := atomic.LoadInt32(&m.v); v >= 0 && atomic.SwapInt32(&m.v, -1) == 1 {
            return
        }

        <-m.ch
    }
}

4.无等待锁

如果没有拿到锁值,会直接返回。

func (m *Mutex) TryLock() bool {
    v := atomic.LoadInt32(&m.v)
    if v <= 0 {
        return false
    }
    return atomic.CompareAndSwapInt32(&m.v, 1, 0)
}

5.释放锁

释放锁时,向信道发送值以唤醒阻塞的协程。

func (m *Mutex) Unlock() {
    if atomic.SwapInt32(&m.v, 1) == 0 {
        return
    }

    select {
    case m.ch <- struct{}{}:
    default:
    }
}

6.使用示例

通过对上锁时机的控制,我们让GetCount()直接返回了-1,实现了无等待锁。

var (
    count      int
    countGuard *Mutex
)

func GetCount() int {
    if countGuard.TryLock() {
        countGuard.Unlock()
        return count
    } else {
        return -1
    }
}

func SetCount(c int) {
    countGuard.Lock()
    time.Sleep(time.Second * 2)
    count = c
    countGuard.Unlock()
}

func main() {
    countGuard = new(Mutex)
    countGuard.Init()

    go SetCount(1)
    time.Sleep(time.Second)
    fmt.Println(GetCount())
}

标签:总结,return,countGuard,组件,Mutex,atomic,func,time,Go
From: https://www.cnblogs.com/qxcheng/p/17158184.html

相关文章

  • 今日总结
    今天是周日,我还在发烧中,这是第四天了,上午头晕的厉害,还很痛,全校部分人群爆发甲型流感,似乎各地均有这种病例。希望大家注意身体,保护好自己。下午写了作业,完成了两科三项作业......
  • Java高级[计专]助教工作总结
    一、助教工作的具体职责和任务负责协助老师发布云班课作业负责帮助老师定期收集同学们的意见与建议同学们作业互评结束后负责审查作业分值异常的作业使用爬虫对作业数......
  • vue3动态组件
    markRow:标记一个对象,使其不能成为一个响应式对象。toRaw:将响应式对象(由reactive定义的响应式)转换为普通对象。shallowRef:只处理基本数据类型的响应式,不进行对象的响应式......
  • vue3异步组件(defineAsyncComponent、Suspense的使用)
    异步组件按需引入,用到的时候再加载,异步组件的引入需要用​​defineAsyncComponent​​进行注册。​​defineAsyncComponent​​工厂函数需要返回一个Promise对象,接收对象类......
  • 素数性质的总结
    素数的性质分类一、素数的性质1.任何大于一的数,要么是素数,要么可以分解为几个素数之积,且分解方式唯一。2.素数的个数有无限个。(欧几里得《几何原本》)3.若n为大于或等......
  • go结构体打印格式化成json
    需要用到json.MarshalIndent方法官方的注释是:MarshalIndent类似于Marshal,但应用Indent来格式化输出。输出中的每个JSON元素都将以一个新行开始,该新行以前缀开头,后跟......
  • vue3 通过文件名称 插槽里只显示指定名称组件
    vue3过滤插槽里的组件获取到插槽,也就是VNode,根据type的名称把不符合名称的组件过滤出去想实现类似ElementUI的select效果,在el-sleect组件中放文本div或是别的组件都不显......
  • 03_23_JavaWeb||day31_JDBC常见6种形式||day31_JDBC常见6种形式【总结篇】
    一、抛出异常的四种基本形式JdbcTestT.java中packagecom.jdbc;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.Prep......
  • 今日总结-HTML视频音频图片实现代码
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>图片音频视频学习</title></head><body><!--img:定义图片src:规定显示图片......
  • Python3中zip()函数知识点总结
    1.引言在本文中,我将带领大家深入了解​​Python​​中的​​zip()​​函数,使用它可以提升大家的工作效率。闲话少说,我们直接开始吧!2.基础知识首先,我们来介绍一些基础知识......