如何使用filestream锁定Linux中的文件?
如下面的示例所示,创建文件在Windows中非常有效,在释放流之前,文件是锁定的,不能在其他会话中被删除或写入。在Linux下,我可以删除文件或在其他会话中写入文件,而不会出现任何问题。
var f: TFileStream;
...
f := TFileStream.Create(TPath.Combine(FTemp, lowerCase(Name)), fmOpenReadWrite + fmCreate);
...
新发现1.1.2020
Linux不会像Windows那样对文件自动应用原子锁。因此,我尝试在创建文件之后应用一个锁:
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);
在创建文件和锁定文件时,有一个小的竞争条件,这不是一个步骤,但对于我的应用程序来说,这不是一个问题。在查看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
与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
区别在于表示独占锁的大W。
不幸的是,这并没有解决这个问题,因为创建第二个filestream只是在同一个进程中创建第二个排他锁,而从另一个进程中删除文件仍然是可能的。如果有一种方法从德尔菲内部读取lsof <file>
的扩展属性.
另一个发现(新年,新想法)
当我以单元测试的形式运行测试并在同一个进程中创建多个对象以测试锁时,这可能是原因,因为即使在同一个进程中,Windows也不允许访问锁定的文件。这在Linux中似乎是不同的。我需要一些类似于Windows的东西--如果它被锁在不同的进程或同一进程的线程中,那就没有什么区别了。也许Linux提供了一种完全不同的方式来实现这样的锁定机制?
尽管如此:任何帮助都是非常感谢的!
发布于 2020-01-01 13:59:52
最后,我找到了一个实用的解决方案,至少满足了我的需求:
在Windows中,我继续使用fmShareExclusive的简单方法。在Linux中,我应用了一个FileLock,如问题中所述。为了检查独占锁,我通过popen运行命令行,并在删除锁文件之前捕获结果,然后创建/锁定它。
lsof -Fl <my flock file name>
如果存在锁,这将输出三行:
p7590
f14
lW
我在结果中查找lW
,该结果指示文件上的独占锁,并且我可以根据需要对此作出反应。
如果进程崩溃,则此解决方案仍然有效,然后文件锁也将消失。
我意识到,这不是一个非常优雅的解决方案,但它似乎足够可靠。
欢迎您提出意见和建议!
https://stackoverflow.com/questions/59492174
复制相似问题