文件系统如何实现扇区锁定?

时间:2013-12-04 01:47:57

标签: java filesystems locking shared-memory

虽然这是一般性问题,但欢迎任何Windows或Linux或Mac支持的文件系统的具体答案。

文件系统如何阻止两个或多个进程对本地驱动器的扇区进行并发读/写访问?

据我所知,显然需要使用某种类型的扇区锁定,但是......

  1. 这个OS范围的扇区锁的'类型'是什么:

    a)命名互斥/命名信号量/文件映射? (在Windows上)

    b)共享内存? (在Linux上)

  2. 这个扇区锁保存在哪里:在内存中?在磁盘上?在任何一种情况下,无论何处存储此锁,我都明白......

    a)锁的存储必须是逻辑临时存储,因为如果其所有者进程崩溃,则不应永久或无限地保持锁定。因此,如果内存中存在这些锁,它会有所帮助。

    b)所有进程都必须通过名称或ID公开发现锁的下落,该名称或ID发现了扇区号的功能。因此,如果进程A需要锁定扇区S,A应该知道如何首先访问扇区S的锁L(S),如果它不存在则创建L(S),尝试锁定L(S),并返回或阻止 - 所有原子,因为另一个进程B也可能与A一起试图执行相同的步骤序列。

  3. 对于大型存储设备,扇区数量也会很大。因此,每个扇区的锁定显然不能在内存或磁盘上预先分配。

  4. 然而,我不知道或不了解的是,Windows上的Linux,FAT *和NTFS上的ext *文件系统已经解决了这个问题,同样对于Mac也是如此。

    我的问题的实际背景:最终,我必须将上面的答案应用于基于Java的自定义文件系统,我正在使用Java 7 NIO2 {{1其中2个或更多独立Java进程可以访问附加驱动器的一堆扇区进行读/写。在Java 7中,我知道在进程之间实现共享内存的唯一非JNI方式是FileSystemProvider。但问题是,这个字节缓冲区将是“原始”内存 - 而我需要的是一个OS范围的互斥体类型机制,并且每个扇区S也可能是一个互斥体。看来,我对此更改了{{1除非我也调用MappedByteBuffer.force

    ,否则不会在原子操作系统上执行

    非常感谢所有答案和评论。

1 个答案:

答案 0 :(得分:2)

我认为你对现代文件系统的实现方式感到困惑,旧系统通常不是多用户;用这个前言让我们看一下叫journal的东西。现在有一些替代方案 - 即

  1. Soft updates
  2. Log-structured file system
  3. Copy-on-write

但是,最常见的可能是日记文件系统。它写入空块并简单地在写入完成时移动指针(同时原子地写入“日志”),这允许在电源故障(或其他写入中断)的情况下“快速”恢复。

至于在系统级别锁定“日志”,我可能会使用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?