Filesystems 文件系统如何处理并发读/写?

Filesystems 文件系统如何处理并发读/写?,filesystems,locking,Filesystems,Locking,用户A要求系统读取文件foo,同时用户B希望将其数据保存到同一文件中。如何在文件系统级别处理这种情况?大多数文件系统(但不是全部)使用锁定来保护对同一文件的并发访问。该锁可以是独占的,因此第一个获得该锁的用户可以获得访问权限-后续用户将获得“拒绝访问”错误。在您的示例场景中,用户A将能够读取文件并获得文件锁,但当用户A读取时,用户B将无法写入 某些文件系统(例如NTFS)允许指定锁定级别,例如允许并发读卡器,但不允许写入器。字节范围锁也是可能的 与数据库不同,文件系统通常不是事务性的,不是原子性

用户A要求系统读取文件
foo
,同时用户B希望将其数据保存到同一文件中。如何在文件系统级别处理这种情况?

大多数文件系统(但不是全部)使用锁定来保护对同一文件的并发访问。该锁可以是独占的,因此第一个获得该锁的用户可以获得访问权限-后续用户将获得“拒绝访问”错误。在您的示例场景中,用户A将能够读取文件并获得文件锁,但当用户A读取时,用户B将无法写入

某些文件系统(例如NTFS)允许指定锁定级别,例如允许并发读卡器,但不允许写入器。字节范围锁也是可能的

与数据库不同,文件系统通常不是事务性的,不是原子性的,来自不同用户的更改也不是孤立的(如果可以看到更改,那么锁定可能会禁止这样做)

使用全文件锁是一种粗粒度的方法,但它可以防止不一致的更新。并非所有的文件系统都支持全文件锁,因此通常使用锁文件——一个通常为空的文件,其存在表明其关联的文件正在使用中。(在大多数文件系统上,创建文件是一项原子操作。)


对于Linux,简单的回答是,如果存在并发编写器,您可以从文件中获取一些奇怪的信息。内核确实在内部使用锁定来串行运行每个read()和write()操作。(虽然,我忘记了整个文件是否已锁定,或者是否处于每页粒度上。)但如果应用程序使用多个write()调用将信息写入文件,则在这些调用之间可能会发生read(),因此它可能会看到不一致的数据。这是操作系统中的一个错误

正如mdma所提到的,您可以使用来确保一次只有一个读卡器和一个写卡器。听起来好像NTFS使用强制锁定,如果一个程序锁定了文件,那么所有其他程序在试图访问该文件时都会收到错误消息


Unix程序通常根本不使用锁定,当它们使用锁定时,锁定通常是建议性的。建议锁仅防止其他进程在同一文件上获得建议锁;它实际上并不阻止读或写。(也就是说,它只为检查锁定的人锁定文件。)

锁定对整个文件还是对部分文件(块/索引节点/任何东西)也有效?答案是特定于文件系统的(毫无疑问,您已经从其他答案中获得了答案)。Windows在大多数情况下使用全文件锁定,因为这是打开文件(CreateFile)的API的一部分。字节范围锁定是可用的,但应用程序必须使用不同的API函数(LockFile)专门请求文件区域的锁定。