golang实现简单的可重入锁

公祖
• 阅读 622
package main

import (
    "fmt"
    "github.com/petermattis/goid"
    "sync"
    "sync/atomic"
)

// Go version: V1.21.0
type ReentryMutex struct {
     sync.Mutex
     owner int64//当前锁的拥有者 goroutineid
     reentry int32//重入次数

}

func (r *ReentryMutex)Lock(){
    gid:=goid.Get()
    //如果锁的拥有者已经是当前goroutine,记录下他已经重入的次数
    if atomic.LoadInt64(&r.owner)==gid{
        r.reentry++
        return
    }
    r.Mutex.Lock()
    atomic.StoreInt64(&r.owner,gid)
    //初始化可访问次数
    r.reentry=1
}


func (r *ReentryMutex) Unlock(){
    gid:=goid.Get()
    //如果解锁协程不是当前协程的拥有者,就panic

    if atomic.LoadInt64(&r.owner)!=gid{
        panic(any(fmt.Sprintf("wrong the owner(%d): %d!",r.owner,gid)))

    }
    r.reentry--

    if r.reentry==0{
        atomic.StoreInt64(&r.owner,-1)
        r.Mutex.Unlock()
    }

}


func main() {
    var wg sync.WaitGroup

    reentryMutex:=ReentryMutex{}
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(index int) {
            defer wg.Done()

            reentryMutex.Lock()
            defer reentryMutex.Unlock()

            fmt.Printf("Goroutine %d acquired the lock.\n", index)
            reentryMutex.Lock()
            defer reentryMutex.Unlock()

            fmt.Printf("Goroutine %d acquired the lock again.\n", index)
        }(i)
    }

    wg.Wait()

    fmt.Println("All goroutines have finished.")

}
点赞
收藏
评论区
推荐文章
Jacquelyn38 Jacquelyn38
4年前
用了这 7 个 VS Code 插件,想写一辈子代码
0\.往期精彩工具推荐译文来自https://levelup.gitconnected.com/7vscodeextensionsthatmakeyouwanttokeepcodingforeverf205e597ae34原作者Daan译者:蓝色的秋风(github
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Souleigh ✨ Souleigh ✨
4年前
34 个 JavaScript 代码优化技巧
1. 含有多个条件的if语句我们可以在数组中存储多个值,并且可以使用数组的includes方法。//longhandif (x  'abc' || x  'def' || x  'ghi' || x 'jkl') {    //logic}//shorthandif ('abc', 'def
Wesley13 Wesley13
3年前
Unity XLua 官方案例学习
1\.Helloworld1usingUnityEngine;2usingXLua;34publicclassHelloworld:MonoBehaviour{5//Usethisforinitialization
Wesley13 Wesley13
3年前
Oracle JDK7 bug 发现、分析与解决实战
本文首发于vivo互联网技术微信公众号链接:https://mp.weixin.qq.com/s/8f34CaTpWz5pTHKA0Xeg(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmp.weixin.qq.com%2Fs%2F8f34CaTpWz5p
Wesley13 Wesley13
3年前
Java日期时间API系列34
  通过Java日期时间API系列9Jdk8中java.time包中的新的日期时间API类的Period和Duration的区别(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fxkzhangsanx%2Fp%2F12110137.html)
Stella981 Stella981
3年前
Redis4.0.0 安装及配置 (Linux — Centos7)
Redis4.0.0安装及配置(Linux—Centos7)!96(http://cdn2.jianshu.io/assets/default_avatar/43397163ecdb3855a0a4139c34a695885.jpg?imageMogr2/autoor
Stella981 Stella981
3年前
Kali Day01
1root@kali:~/文档arpspoofieth0t172.20.151.172.20.151.1234:64:a9:36:4:b70:0:0:0:0:0080642:arpreply172.20.151.1isat34:64:a9:36:4:b7334:64:a9:36:4
Stella981 Stella981
3年前
Android蓝牙连接汽车OBD设备
//设备连接public class BluetoothConnect implements Runnable {    private static final UUID CONNECT_UUID  UUID.fromString("0000110100001000800000805F9B34FB");
Stella981 Stella981
3年前
OS X Mavericks 10.9.5 (13F34) bt下载地址
OSXMavericks10.9.5(13F34),源http://bitsnoop.com/osxmavericks109513f34dmgq68447977.html磁力链magnet:?xturn:btih:4c887e73cd37228d8dc0746315501edc289acc51&dnOS%20X%2
Wesley13 Wesley13
3年前
34.TCP取样器
阅读文本大概需要3分钟。1、TCP取样器的作用   TCP取样器作用就是通过TCP/IP协议来连接服务器,然后发送数据和接收数据。2、TCP取样器详解!(https://oscimg.oschina.net/oscnet/32a9b19ba1db00f321d22a0f33bcfb68a0d.png)TCPClien
公祖
公祖
Lv1
抽刀断水水更流,举杯销愁愁更愁。
文章
4
粉丝
0
获赞
0