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 = ferr = 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包来实现文件/目录的加锁,解锁 2. syscall包属于文件锁,是比较底层的技术,并不能在所有操作系统上完全实现,linux上实现了,windows下面就没有 3. 加锁时调用syscall.Flock(fd&#…...

数据库数据恢复-Syabse数据库存储页底层数据杂乱的数据恢复案例
数据库恢复环境: Sybase版本:SQL Anywhere 8.0。 数据库故障: 数据库所在的设备意外断电后,数据库无法启动。 错误提示: 使用Sybase Central连接后报错: 数据库故障分析: 经过北亚企安数据恢复…...

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

微信小程序开发,小程序类目符合,线上版本无权限申请wx.getLocation接口
我开发 的小程序类目符合wx.getLocation接口的申请标准 但是却还是显示无权限申请 后来研究好久才发现,小程序需要在发布线上版本时提交用户隐私保护指引 如未设置也可以在 设置-服务内容声明-用户隐私保护指引-声明处理用户信息项并补充填写后提交用户隐私协议审核…...
vue2企业级项目(五)
vue2企业级项目(五) 页面适配、主题切换 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)(视频讲解全部题目)) Codeforces Round 888 (Div. 3)(A–G)全部题目详解 A Escalator Conversations #include<bits/stdc.h> #define endl \n #define INF 0x3f3f3f3f using namesp…...

MySQL之深入InnoDB存储引擎——物理文件
文章目录 一、参数文件二、日志文件三、表结构定义文件四、InnoDB 存储引擎文件1、表空间文件2、重做日志文件 一、参数文件 当 MySQL 实例启动时,数据库会先去读一个配置参数文件,用来寻找数据库的各种文件所在位置以及指定某些初始化参数。在默认情况…...
Jquery操作html常用函数
1. text() 获取元素的文本内容:$("#element").text(); 设置元素的文本内容:$("#element").text("New Text"); 2. html() 获取元素的 HTML 内容:$("#element").html(); 设置元素的 HTML 内容&am…...

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

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

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

统信UOS安装mysql数据库(mariadb)-统信UOS安装JDK-统信UOS安装nginx(附安装包)
统信UOS离线全套安装教程(手把手教程) 银河麒麟的各种离线全套安装教程: https://blog.csdn.net/ACCPluzhiqi/article/details/131988147 1.统信UOS桌面系统安装mysql(mariadb) 2.统信UOS桌面系统安装JDK 3.统信UOS桌…...

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

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

从0-1实现简易Raft分布式共识算法
一、Raft前置简介 Raft目前是最著名的分布式共识性算法,被广泛的应用在各种分布式框架、组件中,如Redis、RocketMq、Kafka、Nacos(CP)等 根据Raft论文,可将Raft拆分为如下4个功能模块: 领导者选举日志同…...

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

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

vue3 +ts 报错 index.vue 不是模块
那是因为index.vue中创建了一个空的script标签,而且语法使用的是ts语法。vue-cli会用ts语法解析和校验 如果是无状态组件,删掉 如果是有状态组件,导出该组件的实例 去掉null的script后:...

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

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...

STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...

密码学基础——SM4算法
博客主页:christine-rr-CSDN博客 专栏主页:密码学 📌 【今日更新】📌 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 编辑…...