How to implement cross platform file lock in GO

huangapple go评论77阅读模式
英文:

How to implement cross platform file lock in GO

问题

我需要在GO中实现以下行为:

  1. 一个进程应该能够读取文件,无论其他进程是否锁定了该文件进行写操作。
  2. 一个进程在写入文件之前应该获取写锁。这是为了确保多个进程不能写入同一个文件。
  3. 如果无法获取写锁,进程不应该等待,而是继续执行。

对于基于UNIX的系统,GO中的syscall包定义了flock函数,可以使用以下方式实现上述行为:

  1. 使用syscall.flock函数和LOCK_EX | LOCK_NB尝试在写入文件之前获取锁。
  2. 在读取文件之前不要检查任何锁。

GO中的Windows的syscall包不包括flock。鉴于此,如何编写能够在跨平台上执行并具有上述行为的代码最佳?

我希望尝试实现这一点,而不需要进行特定于操作系统的调用或使用不安全的操作。

PS:我不想要强制文件锁定,进程将在执行文件操作之前检查文件锁定。

英文:

I need to implement the following behavior in GO:

  1. A process should be able to read a file irrespective if any other process has locked the file for writing
  2. A process should obtain a write lock, before it can write to the file. This is to ensure that multiple processes cannot write to the same file
  3. A process should not wait to obtain the write lock, if it cannot obtain a lock it should move on

For UNIX based systems, syscall package in GO defines flock function, which could be used to implement the above behaviour in the following manner:

  1. Use syscall.flock function with LOCK_EX | LOCK_NB to try and obtain a lock before writing to the file
  2. Do not check for any locks before reading from the file

syscall package for Windows in GO, does not include flock. Given this, how best can I write code that can execute cross-platform and has the behavior described above?

I want to try and achieve this without making OS specific calls or using unsafe.

PS: I do not want mandatory file locking, the processes will check for file lock before performing file operations

答案1

得分: 0

使用编译器标志。

Windows的标志:

// +build windows,!linux
...

Linux的标志:

// +build linux,!windows
...

如果你想使用平台本地的锁定函数。

一个解决方法可能是在各个平台上分配资源,比如绑定到一个端口,并依赖于只能进行一次绑定的可能性。绑定操作的错误条件将是决定因素。

个人而言,我会选择使用平台本地选项,并创建一个接口,以便可以轻松添加测试,并确保事情不会出错。

英文:

Use compiler flags.

Flags for windows:

// +build windows,!linux
...

Flags for linux:

// +build linux,!windows
...

If you want to use platform native locking functions.

A workaround might be to allocate resources which are (supposedly) singletons across platforms like binding to a port and relying on that being possible only once. The error condition of the bind operation will be the deciding factor.

Personally I'd go with the option to use platform native options and just make an interface so that one can add tests easily and thereby make sure that things won't break.

huangapple
  • 本文由 发表于 2015年9月26日 22:40:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/32798354.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定