我知道这是一个理论问题,但尚未得到令人满意的答案。所以想把这个问题放在这里。 我有多个C ++进程(也想知道线程的行为),它们试图同时替换同一文件。在Linux中安全地执行多少操作(使用Ubuntu 14.04和Centos 7)?我需要放锁吗?
谢谢。
答案 0 :(得分:3)
基于Linux的基于Unix的文件系统是围绕inodes的概念设计的,{{3}}是内部记录,描述有关文件的各种元数据。通常,这些文件不会直接被用户或程序与之交互,但是它们的存在使这些文件系统具有某种程度的间接性,从而使它们能够提供一些其他操作系统(如Windows)无法使用的有用语义。
filename --> inode --> data
特别是,当文件被删除时,实际上发生的是文件的inode与文件名的分离。而不是(有必要)删除文件数据本身。也就是说,文件及其内容可以继续存在(尽管从用户的角度来看是看不见的),直到所有进程都关闭了在该文件上打开的文件句柄为止。一旦索引节点不再可用于任何进程,只有,文件系统才会将文件的数据块实际标记为空闲且可供重用。同时,即使从技术上讲旧文件的inode /数据仍然存在,文件名仍可用于与另一个文件的inode(和数据)相关联。
其结果是,在Linux下,即使其他线程/进程正在使用它,也可以随时删除(或重命名)文件,这是完全有效的。您的删除操作将会成功,并且在那个瞬间打开该文件的所有其他程序都可以继续读取/写入/使用该文件,就像未删除该文件一样。唯一不同的是文件名将不再出现在其目录中,并且当他们在文件上调用fclose()
(或close()
等)时,文件的数据将消失。>
由于执行mv new.txt old.txt
与执行rm old.txt ; mv new.txt old.txt
基本相同,因此在没有任何同步的情况下从多个线程执行此操作应该没有问题。 (请注意,具有多个线程或进程同时打开同一文件并同时写入该文件的情况稍有不同;危险不会崩溃,但它们很容易覆盖彼此的数据并损坏文件,如果他们不小心)
答案 1 :(得分:0)
这在很大程度上取决于您将要做什么以及如何使用文件。通常,在像Linux这样的Unix / Posix系统中,如果有多个进程进行,则所有文件调用都将成功,并且操作系统处理争用的一般方式是“最后一个胜出的方法”。本质上,对文件系统的所有修改都已序列化,因此文件系统始终处于一致状态。否则,它是免费的。
尽管这里有很多细节。在打开O_EXCL
之类的文件时使用了一些标志,如果先执行另一个进程(某种锁),则可能导致失败。对于文件内容,有一个flock
锁定(例如,键入man 2 flock
以了解更多信息)的建议(也就是,操作系统没有强迫任何人关注它们)。还有更多针对Linux的强制性锁定系统。
还有诸如“如果有人删除了我打开的文件会怎样?”之类的详细信息。另一个答案正确而正确地解释了。
最后,围绕着整个细节,是否可以确保永久记录文件系统的任何特定更改,或者如果有人轻按电源开关它是否有消失的可能。而且,一旦您真正深入其中,就变成了一个半烂摊子,在操作系统所依赖的狡猾硬件与涉及此问题不同方面的各种Linux系统调用令人困惑的烦恼之间,这些问题通常来自不同时代的Linux。 Unix / Posix的历史,并以奇怪而神秘的方式彼此交互。
因此,对于这个非常笼统且开放性的问题,答案必须一定是含糊,抽象和动摇。