虽然这是一般性问题,但欢迎任何Windows或Linux或Mac支持的文件系统的具体答案。
文件系统如何阻止两个或多个进程对本地驱动器的扇区进行并发读/写访问?
据我所知,显然需要使用某种类型的扇区锁定,但是......
这个OS范围的扇区锁的'类型'是什么:
a)命名互斥/命名信号量/文件映射? (在Windows上)
b)共享内存? (在Linux上)
这个扇区锁保存在哪里:在内存中?在磁盘上?在任何一种情况下,无论何处存储此锁,我都明白......
a)锁的存储必须是逻辑临时存储,因为如果其所有者进程崩溃,则不应永久或无限地保持锁定。因此,如果内存中存在这些锁,它会有所帮助。
b)所有进程都必须通过名称或ID公开发现锁的下落,该名称或ID发现了扇区号的功能。因此,如果进程A需要锁定扇区S,A应该知道如何首先访问扇区S的锁L(S),如果它不存在则创建L(S),尝试锁定L(S),并返回或阻止 - 所有原子,因为另一个进程B也可能与A一起试图执行相同的步骤序列。对于大型存储设备,扇区数量也会很大。因此,每个扇区的锁定显然不能在内存或磁盘上预先分配。
然而,我不知道或不了解的是,Windows上的Linux,FAT *和NTFS上的ext *文件系统已经解决了这个问题,同样对于Mac也是如此。
我的问题的实际背景:最终,我必须将上面的答案应用于基于Java的自定义文件系统,我正在使用Java 7 NIO2 {{1其中2个或更多独立Java进程可以访问附加驱动器的一堆扇区进行读/写。在Java 7中,我知道在进程之间实现共享内存的唯一非JNI方式是FileSystemProvider
。但问题是,这个字节缓冲区将是“原始”内存 - 而我需要的是一个OS范围的互斥体类型机制,并且每个扇区S也可能是一个互斥体。看来,我对此更改了{{1除非我也调用MappedByteBuffer.force
。
非常感谢所有答案和评论。
答案 0 :(得分:2)
我认为你对现代文件系统的实现方式感到困惑,旧系统通常不是多用户;用这个前言让我们看一下叫journal的东西。现在有一些替代方案 - 即
但是,最常见的可能是日记文件系统。它写入空块并简单地在写入完成时移动指针(同时原子地写入“日志”),这允许在电源故障(或其他写入中断)的情况下“快速”恢复。
至于在系统级别锁定“日志”,我可能会使用FileLock之类的 -
FileLock lock = null;
FileChannel channel = null;
try {
// Get a file channel for the file
File file = new File("journal");
channel = new RandomAccessFile(file,
"rw").getChannel();
// Try acquiring the lock without blocking.
try {
lock = channel.tryLock();
if (lock != null) {
// GOT THE LOCK.... DO WORK...
return true; // write success.
}
} catch (OverlappingFileLockException e) {
// File is already locked in this thread or virtual
// machine
} finally {
if (lock != null) {
lock.release(); // Release the lock
}
if (channel != null) {
channel.close(); // Close the file.
}
}
return false; // Write must be retried?