golang: fcntl文件锁
进程级强制锁,ubuntu的apt和dpkg进程使用此锁
1 锁结构
type Flock_t struct { Type int16 //锁的类型: 读锁、写锁、解锁 Whence int16 //锁的范围 SEEK_SET, SEEK_CUR, SEEK_END 文件开头,当前位置,结尾。基准位置 Pad_cgo_0 [4]byte Start int64 //相对于基准的偏移值。定义了锁的起始 Len int64 //锁字节即从偏移开始的连续字节数 Pid int32 //获取哪个进程处于阻塞(F_GETLK) Pad_cgo_1 [4]byte }
对于一个文件,flock加锁的范围是整个文件内容,而fcntl能对文件的任意部分加锁。
2 获取锁状态
package main import ( "fmt" "syscall" ) func main() { fd, err := syscall.Open("/var/lib/dpkg/lock-frontend", syscall.O_WRONLY, 0644) if err != nil { fmt.Println(err) } defer syscall.Close(fd) // 声明一个锁结构体用于写入锁状态 fgetlk := syscall.Flock_t{} /* FcntlFlock(fd uintptr, cmd int, lk *Flock_t) cmd: 使用F_GETLK获取锁状态并写入lk中 */ err = syscall.FcntlFlock(uintptr(fd), syscall.F_GETLK, &fgetlk) if err != nil { fmt.Println(err) } fmt.Printf("%#v\n", fgetlk) /* F_RDLCK = 0x0 读锁 F_WRLCK = 0x1 写锁 F_UNLCK = 0x2 解锁 */ switch fgetlk.Type { case syscall.F_WRLCK: fmt.Println("write lock") case syscall.F_RDLCK: fmt.Println("read lock") case syscall.F_UNLCK: fmt.Println("unlock") default: } }
3 加写锁
package main import ( "fmt" "io" "os" "syscall" "time" ) func main() { fp := "/var/lib/dpkg/lock-frontend" file, err := os.OpenFile(fp, os.O_WRONLY, os.ModePerm) if err != nil { fmt.Println(err) return } fd := file.Fd() flockt := syscall.Flock_t{ Type: syscall.F_WRLCK, Whence: io.SeekStart, } /* F_GETLK: 获取当前锁的状态 F_SETLK: 给当前文件上锁(非阻塞) F_SETLKW: 给当前文件上阻塞锁(类似自旋锁) 读/写、写/写互斥, 读/读不互斥 */ err = syscall.FcntlFlock(fd, syscall.F_SETLK, &flockt) if err != nil { fmt.Println(err) return } fmt.Println("加锁成功") time.Sleep(time.Second * 15) flockt.Type = syscall.F_UNLCK syscall.FcntlFlock(fd, syscall.F_SETLK, &flockt) fmt.Println("解锁成功") // 这是其他进程即可获取锁 time.Sleep(time.Second * 15) }
读锁
打开文件方法使用读方法打开os.Open() 或者os.OpenFile(fp, os.O_RDONLY, perm)
锁类型使用读锁, syscall.Flock_t
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类