文件系统如何处理并发的读写操作?

81

用户A请求系统读取文件foo,同时用户B想将他或她的数据保存到同一个文件中。在文件系统层面上如何处理这种情况?

2个回答

59

大多数文件系统(但并非所有)使用锁定来保护对同一文件的并发访问。该锁可以是排他性的,因此第一个获取锁的用户可以访问 - 后续用户会收到“访问被拒绝”的错误。在您的示例场景中,用户A将能够读取文件并获得文件锁,但用户B在用户A读取时将无法写入。

某些文件系统(例如NTFS)允许指定锁定级别,例如允许并发读取器但不允许写入器。还可以进行字节范围锁定。

与数据库不同,文件系统通常不是事务性的,不具备原子性,并且来自不同用户的更改未隔离(如果甚至可以看到更改-锁定可能会禁止此操作。)

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


锁定是针对整个文件还是针对其部分(块/索引节点/其他)进行的? - Matteo Riva
3
答案是与文件系统相关的(正如您从其他答案中无疑所得出的结论)。对于大多数情况,Windows 使用整个文件锁定,因为这是打开文件的 API 的一部分(CreateFile)。字节范围锁定也是可用的,但应用程序必须使用不同的 API 函数(LockFile)特别请求文件区域的锁定。 - mdma

45
对于Linux系统而言,简单来说,如果有并发写入,则从文件中获取的信息可能会出现一些奇怪的情况。内核在运行每个read()write()操作时会使用锁定。 (尽管我忘记了整个文件是否被锁定或者它是以每页为粒度的。)但是,如果应用程序使用多个write()调用将信息写入文件,则read()可能会在这些调用之间发生,因此它可能会看到不一致的数据。这是操作系统中的atomicity violation
正如mdma所提到的,您可以使用file locking确保同时只有一个读者和一个写者。听起来NTFS使用mandatory locking,其中如果一个程序锁定了文件,则所有其他程序在尝试访问该文件时都会收到错误消息。
Unix程序通常根本不使用锁定,而当它们使用锁定时,锁定通常是advisory的。建议性锁定仅防止其他进程在同一文件上获得建议性锁定;它实际上不会阻止读取或写入。(也就是说,它仅为检查锁定的人锁定文件。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接