龙空技术网

文件锁(golang实现)

浩仔浩仔 80

前言:

此时姐妹们对“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锁实现