前言:
此时姐妹们对“golang锁实现”大概比较注意,咱们都需要学习一些“golang锁实现”的相关文章。那么小编同时在网上网罗了一些关于“golang锁实现””的相关文章,希望同学们能喜欢,同学们快快来了解一下吧!文件锁(file locking)是一种互斥机制,常常用来确保文件可以被多个进程以安全的方式读取/写入。解决多个进程产生的竞态条件(race condition,即系统的实质性行为取决于其他不可控事件的顺序或时间,即结果取决于顺序)。
例如:
如图,执行的顺序不同,最终的结果不同。
linux为我们提供了两种文件锁:建议锁(Advisory Locking)和强制锁(Mandatory Locking)。
建议锁:
只有当参与的所有进程通过显式获取锁时,它才会起作用。否则,如果进程根本不知道锁,建议锁将被忽略。
强制锁:
linux明确指出“linux对强制锁的实现是不稳定的”,所以这种锁很少用到。而且锁定前需要mount -o mand FILESYSTEM MOUNT_POINT等命令,所以我们暂不提此锁。
用到的命令:
使用flock命令进行建议锁的加解锁,使用lslocks命令可以查询文件锁。
代码实现:
flock.go
package mainimport ( "io/ioutil" "os" "strconv" "time" "golang.org/x/sys/unix")const ( ProtectedFileName = "foo.txt" FileLockName = "flock.lock")func main() { defer func() { UnlockFile(FileLockName) }() for LockFile(FileLockName) != nil { } content, _ := ioutil.ReadFile(ProtectedFileName) i, _ := strconv.ParseInt(string(content), 10, 64) time.Sleep(1 * time.Second) ioutil.WriteFile(ProtectedFileName, []byte(strconv.FormatInt(i+80, 10)), 0777)}func LockFile(fileName string) error { f, err := os.Create(fileName) if err != nil { return err } return unix.Flock(int(f.Fd()), unix.LOCK_EX|unix.LOCK_NB) // exclusive, nonblock}func UnlockFile(fileName string) error { f, err := os.Open(fileName) if err != nil { return err } defer f.Close() if err := unix.Flock(int(f.Fd()), unix.LOCK_UN); err != nil { // unlock return err } if err := os.Remove(fileName); err != nil { return err } return nil}
这个程序给foo.txt文件中的数字加80然后回写。锁文件为flock.lock。
使用go build编译之后,执行:
./flock & ./flock &
多次运行,查看foo.txt文件中的数据,始终是160的整数倍,说明文件锁生效,是正确的。
注意:flock仅针对多个进程之间,同一进程中的线程级别加flock会产生不可控的结果(即时而能锁住时而锁不住)。
标签: #golang锁实现