当前位置: 首页 > news >正文

golang文件锁,目录锁,syscall包的使用

先说结论

1. golang提供了syscall包来实现文件/目录的加锁,解锁

2. syscall包属于文件锁,是比较底层的技术,并不能在所有操作系统上完全实现,linux上实现了,windows下面就没有

3. 加锁时调用syscall.Flock(fd,syscall.LOCK_EX),解锁时调用syscall.Flock(fd, syscall.LOCK_UN)

4. 加锁成功后,对加锁的文件fd进行Close()操作同样会释放锁,切记

代码实现

锁的定义如下内部两个变量:文件/目录的全路径名,文件对象

// 文件锁/目录锁
type DirLock struct {
    dir     string        // 文件/目录的全路径名
    f       *os.File    // 文件对象
}

加锁的实现

核心代码是 syscall.Flock(int(f.Fd()), LOCK_EX|syscall.LOCK_NB),注意其中的标记

LOCK_EX :加锁标记。只有一个进程能加锁成功,其他进程再尝试加锁时会阻塞,等同于我们常用的写锁

LOCK_NB :不阻塞标记。如果其他进程已加锁成功,自己去尝试加锁时就不再阻塞,而是直接返回错误

// 加锁
func (l *DirLock) Lock() error {
    f, err := os.Open(l.dir)
    if err != nil {
        return err
    }
    l.f = f

    err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
    if err != nil {
        return err
    }
    return nil
}

解锁的实现

核心代码是 syscall.Flock(int(l.f.Fd()), syscall.LOCK_UN)

LOCK_UN :解锁标记。如果自己已经加锁成功,可以用此标记去解锁

// 解锁
func (l *DirLock) Unlock() error {
    defer l.f.Close() // 关闭文件

    return syscall.Flock(int(l.f.Fd()), syscall.LOCK_UN) // LOCK_UN表解锁
}

实验

我们建立5个协程,每秒去尝试加锁一次,失败则1秒后重试,成功则持续2秒后解锁

核心代码如下

    // 5个协程,都尝试对目录加锁,加锁失败的就重试,加锁成功的2秒后释放
    for i := 0; i < 5; i++ {
        wg.Add(1)

        go func(num int) {
            dirLock := New(dir)
            ticker := time.NewTicker(time.Second) // 定时器每秒尝试1次
            for {
                select {
                case <-ticker.C:
                    {
                        err := dirLock.Lock() // 加锁尝试
                        if err != nil {
                            fmt.Printf("lock dir failed, goroutine num=%d, err=%s \n", num, err.Error())
                            continue
                        }
                        fmt.Println("lock dir succeed, goroutine num=", num)
                        goto end
                    }
                }
            }

            end:
            time.Sleep(time.Second*2)
            dirLock.Unlock() // 解锁
            wg.Done()
        }(i)
    }
    wg.Wait()

实验结果如下图

完整代码

package main
import ("fmt""os""sync""syscall""time"
)// 目录锁
type DirLock struct {dir 	string		// 目录的全路径名f   	*os.File	// 文件对象
}func New(dir string) *DirLock {return &DirLock{dir: dir,}
}// 加锁
func (l *DirLock) Lock() error {f, err := os.Open(l.dir)if err != nil {return err}l.f = ferr = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)if err != nil {return err}return nil
}// 释放锁
func (l *DirLock) Unlock() error {defer l.f.Close() // 其实不执行Close()也会释放目录锁return syscall.Flock(int(l.f.Fd()), syscall.LOCK_UN)
}func main() {dir, _ := os.Getwd()wg := sync.WaitGroup{}// 5个协程,都尝试对目录加锁,加锁失败的就重试,加锁成功的2秒后释放for i := 0; i < 5; i++ {wg.Add(1)go func(num int) {dirLock := New(dir)ticker := time.NewTicker(time.Second) // 定时器每秒尝试1次for {select {case <-ticker.C:{err := dirLock.Lock() // 加锁尝试if err != nil {fmt.Printf("lock dir failed, goroutine num=%d, err=%s \n", num, err.Error())continue}fmt.Println("lock dir succeed, goroutine num=", num)goto end}}}end:time.Sleep(time.Second*2)dirLock.Unlock() // 解锁wg.Done()}(i)}wg.Wait()
}

相关文章:

golang文件锁,目录锁,syscall包的使用

先说结论 1. golang提供了syscall包来实现文件/目录的加锁&#xff0c;解锁 2. syscall包属于文件锁&#xff0c;是比较底层的技术&#xff0c;并不能在所有操作系统上完全实现&#xff0c;linux上实现了&#xff0c;windows下面就没有 3. 加锁时调用syscall.Flock(fd&#…...

数据库数据恢复-Syabse数据库存储页底层数据杂乱的数据恢复案例

数据库恢复环境&#xff1a; Sybase版本&#xff1a;SQL Anywhere 8.0。 数据库故障&#xff1a; 数据库所在的设备意外断电后&#xff0c;数据库无法启动。 错误提示&#xff1a; 使用Sybase Central连接后报错&#xff1a; 数据库故障分析&#xff1a; 经过北亚企安数据恢复…...

移远通信推出新一代高算力智能模组SG885G-WF,为工业和消费级IoT应用带来全新性能标杆

2023年7月24日&#xff0c;全球领先的物联网整体解决方案供应商移远通信宣布&#xff0c;正式推出其新一代旗舰级安卓智能模组SG885G-WF。该智能模组具有高达48 TOPS 的AI综合算力、强大性能及丰富的多媒体功能&#xff0c;非常适用于需要高处理能力和多媒体功能的工业和消费者…...

微信小程序开发,小程序类目符合,线上版本无权限申请wx.getLocation接口

我开发 的小程序类目符合wx.getLocation接口的申请标准 但是却还是显示无权限申请 后来研究好久才发现&#xff0c;小程序需要在发布线上版本时提交用户隐私保护指引 如未设置也可以在 设置-服务内容声明-用户隐私保护指引-声明处理用户信息项并补充填写后提交用户隐私协议审核…...

vue2企业级项目(五)

vue2企业级项目&#xff08;五&#xff09; 页面适配、主题切换 1、适配 项目下载插件 npm install --save-dev style-resources-loader vue-cli-plugin-style-resources-loader修改vue.config.js部分内容 const path require("path");module.exports {pluginOpt…...

【HTML5】拖放详解及实现案例

文章目录 效果预览代码实现 效果预览 代码实现 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>一颗不甘坠落的流星</title><style>#div1,#div2 {float: left;width: 100px;height: 27px;margin: 10px;paddin…...

Codeforces Round 888 (Div. 3)(视频讲解全部题目)

[TOC](Codeforces Round 888 (Div. 3)&#xff08;视频讲解全部题目&#xff09;) Codeforces Round 888 (Div. 3)&#xff08;A–G&#xff09;全部题目详解 A Escalator Conversations #include<bits/stdc.h> #define endl \n #define INF 0x3f3f3f3f using namesp…...

MySQL之深入InnoDB存储引擎——物理文件

文章目录 一、参数文件二、日志文件三、表结构定义文件四、InnoDB 存储引擎文件1、表空间文件2、重做日志文件 一、参数文件 当 MySQL 实例启动时&#xff0c;数据库会先去读一个配置参数文件&#xff0c;用来寻找数据库的各种文件所在位置以及指定某些初始化参数。在默认情况…...

Jquery操作html常用函数

1. text() 获取元素的文本内容&#xff1a;$("#element").text(); 设置元素的文本内容&#xff1a;$("#element").text("New Text"); 2. html() 获取元素的 HTML 内容&#xff1a;$("#element").html(); 设置元素的 HTML 内容&am…...

【Lua学习笔记】Lua进阶——Table,迭代器

文章目录 官方唯一指定数据结构--tabletable的一万种用法字典和数组 迭代器ipairs()pairs() 回到Table 在【Lua学习笔记】Lua入门中我们讲到了Lua的一些入门知识点&#xff0c;本文将补充Lua的一些进阶知识 官方唯一指定数据结构–table 在上篇文章的最后&#xff0c;我们指出…...

重庆市北斗新型智慧城市政府项目

技术栈&#xff1a;使用vue2JavaScriptElementUIvuexaxiosmapboxcesium 项目描述&#xff1a;重庆市北斗新型智慧城市政府项目是基于千寻孪界开发的一款智慧城市项目&#xff0c;包含车辆实时位置定位&#xff0c;智能设备的报警&#xff0c;基础设施的部设等等功能 工作内容&a…...

FANUC机器人SRVO-217故障报警原因分析及参考解决办法

FANUC机器人SRVO-217故障报警原因分析及参考解决办法 如下图所示,示教器提示:SRVO-217紧急停止电路板未找到, 查阅手册可以看到以下的报警说明: 故障原因: 通电时未能识别紧急停止电路板或者增设的安全I/O装置。连接有多个安全I/O装置的系统中,在报警信息的最后,会显示发…...

统信UOS安装mysql数据库(mariadb)-统信UOS安装JDK-统信UOS安装nginx(附安装包)

统信UOS离线全套安装教程&#xff08;手把手教程&#xff09; 银河麒麟的各种离线全套安装教程&#xff1a; https://blog.csdn.net/ACCPluzhiqi/article/details/131988147 1.统信UOS桌面系统安装mysql&#xff08;mariadb&#xff09; 2.统信UOS桌面系统安装JDK 3.统信UOS桌…...

上门小程序开发|上门服务小程序|上门家政小程序开发

随着移动互联网的普及和发展&#xff0c;上门服务成为了许多人生活中的一部分。上门小程序是一种基于小程序平台的应用程序&#xff0c;它提供了上门服务的在线平台&#xff0c;为用户提供了便捷的上门服务体验。下面将介绍一些适合开发上门小程序的商家。   家政服务商家&am…...

1000道网络安全必备面试题合集,秋招金九银十必看!!!

以下为网络安全各个方向涉及的面试题&#xff0c;星数越多代表问题出现的几率越大&#xff0c;祝各位都能找到满意的工作。 注&#xff1a;本套面试题&#xff0c;已整理成pdf文档&#xff0c;但内容还在持续更新中&#xff0c;因为无论如何都不可能覆盖所有的面试问题&#x…...

从0-1实现简易Raft分布式共识算法

一、Raft前置简介 Raft目前是最著名的分布式共识性算法&#xff0c;被广泛的应用在各种分布式框架、组件中&#xff0c;如Redis、RocketMq、Kafka、Nacos&#xff08;CP&#xff09;等 根据Raft论文&#xff0c;可将Raft拆分为如下4个功能模块&#xff1a; 领导者选举日志同…...

Spring 创建和使用

Spring 是⼀个包含了众多⼯具⽅法的 IoC 容器。既然是容器那么它就具备两个最基本的功能&#xff1a; 将对象存储到容器&#xff08;Spring&#xff09;中&#xff1b; 从容器中将对象取出来。 在 Java 语⾔中对象也叫做 Bean 1.创建 Spring 项目 接下来使⽤ Maven ⽅式来创…...

Javadoc comment自动生成

光标放在第二行 按下Alt Shift j 下面是Java doc的生成 Next Next-> Finish...

vue3 +ts 报错 index.vue 不是模块

那是因为index.vue中创建了一个空的script标签&#xff0c;而且语法使用的是ts语法。vue-cli会用ts语法解析和校验 如果是无状态组件&#xff0c;删掉 如果是有状态组件&#xff0c;导出该组件的实例 去掉null的script后&#xff1a;...

win10 hadoop报错 unable to load native-hadoop library

win10 安装hadoop执行hdfs -namenode format 和运行hadoop的start-all报错 unable to load native-hadoop library 验证&#xff1a; hadoop checknative -a 这个命令返回都是false是错的 返回下图是正确的 winutils: true D:\soft\hadoop-3.0.0\bin\winutils.exe Native li…...

德希科技在线污泥浓度传感器

一、应用场景与产品定位 污泥浓度是污水处理生化系统稳定运行的关键控制指标&#xff0c;研发人员针对市政污水、工业废水处理厂曝气池、二沉池、氧化沟等场景的监测需求&#xff0c;推出散射光法在线污泥浓度传感器。设备以高稳定性、强抗干扰、长寿命的特性&#xff0c;适配…...

MTools开箱即用:5分钟在K8s部署Web版AI工具,图片音视频全能处理

MTools开箱即用&#xff1a;5分钟在K8s部署Web版AI工具&#xff0c;图片音视频全能处理 1. 为什么选择MTools Web版 MTools Web版是一款集成了图片处理、音视频编辑、AI智能工具和开发辅助功能的现代化工具套件。与传统的桌面软件不同&#xff0c;它可以直接在浏览器中运行&a…...

汽车电子电气架构演进:从分布式 ECU 到中央计算平台

目录 一、电子电气架构的六大演进阶段 二、高性能处理器与软件平台重构 三、宝马分层式电子电气架构设计 四、中央通信服务器与可扩展网络 五、车云一体架构与软件开发变革 六、架构升级代码示例&#xff1a;SOA 服务注册与调用 七、中央计算平台配置示例&#xff08;代码…...

基于RFM模型的电商用户价值分层画像分析

摘要本项目旨在通过Python对电商平台用户行为数据进行深度挖掘与分析&#xff0c;以构建用户画像为核心&#xff0c;实现对高价值用户、低价值用户及“白嫖党”的精准分层。项目基于RFM&#xff08;Recency, Frequency, Monetary&#xff09;模型理论&#xff0c;通过数据清洗、…...

Kimi-VL-A3B-Thinking开源大模型部署教程:MoonViT视觉编码器实测解析

Kimi-VL-A3B-Thinking开源大模型部署教程&#xff1a;MoonViT视觉编码器实测解析 1. 模型简介与核心能力 Kimi-VL-A3B-Thinking是一款创新的开源混合专家&#xff08;MoE&#xff09;视觉语言模型&#xff08;VLM&#xff09;&#xff0c;在多模态推理领域展现出卓越性能。这…...

【硬核】K8s GPU调度从入门到“精通”:不止Device Plugin,还有MIG、DRA和那些你踩过的坑

K8s GPU调度从入门到“精通”&#xff1a;不止Device Plugin&#xff0c;还有MIG、DRA和那些你踩过的坑你以为把GPU挂上K8s就万事大吉了&#xff1f;错&#xff01;调度策略、硬隔离、软隔离、抢占回收…每一个环节都可能是你烧钱的坑。本文从实战出发&#xff0c;手把手教你如…...

Java调用动态库总崩溃?从SIGSEGV日志反向定位到C端ABI兼容性缺陷——一线故障复盘(含GDB+Java Core联合调试全流程)

第一章&#xff1a;Java调用动态库总崩溃&#xff1f;从SIGSEGV日志反向定位到C端ABI兼容性缺陷——一线故障复盘&#xff08;含GDBJava Core联合调试全流程&#xff09;某金融风控系统在JDK 17 Alpine Linux&#xff08;musl libc&#xff09;环境下频繁触发 JVM Crash&#…...

Pixel Epic · Wisdom Terminal参数详解:显存配额与智力同步率调优指南

Pixel Epic Wisdom Terminal参数详解&#xff1a;显存配额与智力同步率调优指南 1. 认识像素史诗 智识终端 像素史诗 (Pixel Epic) 是一款基于 AgentCPM-Report 大模型构建的高端研究报告辅助终端。它将枯燥的科研过程转化为一场充满像素美学的RPG冒险&#xff0c;让用户以…...

SWIFT报文格式规范:从字符约束到金融交易安全的深度解析

1. SWIFT报文格式规范的核心价值 第一次接触SWIFT报文时&#xff0c;我被那些看似简单的字母代号震撼到了——谁能想到&#xff0c;像"2!n"这样简单的符号组合&#xff0c;竟然承载着全球金融系统的运转规则&#xff1f;在跨境汇款中输错一个字符可能导致资金滞留数周…...

KDD_CUP99数据集预处理与模型性能验证(附处理代码与数据集)

1. KDD_CUP99数据集入门指南 第一次接触KDD_CUP99数据集时&#xff0c;我也被它庞大的数据量和复杂的特征结构吓了一跳。这个数据集是网络安全领域最经典的入侵检测基准数据集之一&#xff0c;包含了模拟军事网络环境中各种攻击类型的网络连接记录。原始数据集有近500万条记录&…...