简体   繁体   English

Delphi 10.3 Linux 独占文件访问

[英]Delphi 10.3 Linux exclusive file access

How can I lock a file in Linux with a filestream?如何使用文件流在 Linux 中锁定文件?

Creating a filestream like in the example below works perfectly in Windows, the file is locked and cannot be deleted or written to in other sessions until the stream is freed.创建如下示例中的文件流在 Windows 中可以完美运行,文件被锁定并且在释放流之前无法删除或写入其他会话。 Under Linux I can delete the file or write to it in an other session without any problems.在 Linux 下,我可以删除文件或在其他会话中写入文件而不会出现任何问题。

var f: TFileStream;
...
f := TFileStream.Create(TPath.Combine(FTemp, lowerCase(Name)), fmOpenReadWrite + fmCreate);
...

NEW FINDINGS 1.1.2020新发现 1.1.2020

Linux does not automatically apply an atomic lock on files like Windows does. Linux 不会像 Windows 那样自动对文件应用原子锁。 So I tried applying a lock after creating the file:所以我在创建文件后尝试应用锁:

function flock(handle, operation: integer): integer; cdecl; external libc name _PU + 'flock';

const
  LOCK_EX = 2;

...

f := TFileStream.Create(fn, fmCreate, fmShareExclusive);
flock(f.handle, LOCK_EX);

There is a small race condition as creating the file and locking it is not one single step but for my application this is not a problem.有一个小的竞争条件,因为创建文件并锁定它不是一个单一的步骤,但对于我的应用程序来说,这不是问题。 When looking at the created lock file on the linux console the difference is obvious:在 linux 控制台上查看创建的锁定文件时,区别很明显:

Wihout flock():没有羊群():

mint@minti:/tmp/itclock$ lsof wirsing
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
_TestLibB 5417 mint   14u   REG    8,1        8 2755101 wirsing

With flock():随着羊群():

mint@minti:/tmp/itclock$ lsof wirsing
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
_TestLibB 6365 mint   14uW  REG    8,1        0 2755117 wirsing

The difference is the big W that indicates an exclusive lock.区别在于表示排他锁的大 W。

Unfortunately this does not solve the problem as creating a second filestream just creates a second exclusive lock in the same process and deleting the file from an other process is still possible.不幸的是,这并不能解决问题,因为创建第二个文件流只会在同一进程中创建第二个排他锁,而从其他进程中删除该文件仍然是可能的。 If there was a way to read the extended attributes of lsof <file> from within delphi ...如果有一种方法可以从 delphi 中读取lsof <file>的扩展属性......

An other finding (new year, new ideas)另一个发现(新的一年,新的想法)

As I run my tests as unit tests and create several objects in the same process to test the locks this might be the cause as Windows does not allow accessing the locked file even from within the same process.当我将测试作为单元测试运行并在同一进程中创建多个对象来测试锁时,这可能是原因,因为 Windows 甚至不允许从同一进程中访问锁定的文件。 This seems to be different in Linux.这在 Linux 中似乎有所不同。 I need something that behaves like in Windows - it should be no difference if it is locked in a different process or a thread of the same process.我需要一些行为类似于 Windows 的东西 - 如果它被锁定在不同的进程或同一进程的线程中应该没有区别。 Perhaps Linux offers a totally different way to accomplish such a locking mechanism?也许 Linux 提供了一种完全不同的方式来实现这种锁定机制?

And still: Any help is very appreciated!仍然:非常感谢任何帮助!

Finally I found a usable solution that at least serves my requirements:最后,我找到了一个至少满足我要求的可用解决方案:

In Windows I continue using the simple approach with fmShareExclusive.在 Windows 中,我继续使用 fmShareExclusive 的简单方法。 In Linux I apply a FileLock as described above in the question.在 Linux 中,我按照上面的问题应用了 FileLock。 For checking the exclusive lock I run a command line via popen and capture the result prior to deleting the lock file and then creating/locking it.为了检查排他锁,我通过 popen 运行命令行并在删除锁文件然后创建/锁定它之前捕获结果。

lsof -Fl <my flock file name>

This outputs three lines if a Lock exists:如果存在锁,则输出三行:

p7590
f14
lW

I look for lW in the result that indicates an exclusive lock on the file and I can react on that as required.我在结果中查找lW指示文件上的排他锁,我可以根据需要对此做出反应。

This solution still works if a process crashes as then the file lock will be gone too.如果进程崩溃,此解决方案仍然有效,因为文件锁也会消失。

I am aware of the fact that this is not a very elegant solution but it seems to be rubust and reliable enough.我知道这不是一个非常优雅的解决方案,但它似乎足够强大和可靠。

Comments and suggestions are very welcome!非常欢迎提出意见和建议!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM