用户A要求系统读取文件,foo
而用户B同时希望将其数据保存到同一文件中。在文件系统级别如何处理这种情况?
用户A要求系统读取文件,foo
而用户B同时希望将其数据保存到同一文件中。在文件系统级别如何处理这种情况?
Answers:
大多数文件系统(但不是全部)都使用锁定来保护对同一文件的并发访问。锁可以是排他的,因此第一个获得锁的用户将获得访问权限-后续用户将获得“访问被拒绝”错误。在您的示例场景中,用户A将能够读取文件并获得文件锁定,但是用户B在用户A读取时将无法写入文件。
某些文件系统(例如NTFS)允许指定锁定级别,例如允许并发读取器,但不允许写入器。字节范围锁定也是可能的。
与数据库不同,文件系统通常不是事务性的,不是原子性的,并且来自不同用户的更改也不是孤立的(如果甚至可以看到更改,则锁定可能会阻止这种情况。)
使用全文件锁是一种粗粒度的方法,但是它将防止不一致的更新。并非所有文件系统都支持整个文件锁定,因此使用锁定文件是一种常见做法,该文件通常是空文件,其存在表明其关联文件正在使用中。(创建文件是大多数文件系统上的原子操作。)
对于Linux,简短的答案是,如果存在并发写入器,则可以从文件中获取一些奇怪的信息。内核确实在内部使用锁定来依次运行每个read()和write()操作。(尽管,我忘记了整个文件是被锁定还是处于每页的粒度。)但是,如果应用程序使用多个write()调用将信息写入文件,则在任何这些调用之间都可能发生read(),因此它可能会看到不一致的数据。这是操作系统中的原子性违规。
正如mdma所提到的,您可以使用文件锁定来确保一次只有一个读取器和一个写入器。听起来NTFS使用强制锁定,如果一个程序锁定了文件,则其他所有程序在尝试访问该文件时都会收到错误消息。
Unix程序通常根本不使用锁定,当使用锁定时,锁定通常是建议性的。咨询锁仅阻止其他进程在同一文件上获得咨询锁。它实际上并没有阻止读取或写入。(也就是说,它只为那些检查锁定的人锁定文件。)