简体   繁体   English

使用重命名安全地覆盖Linux中的共享文件

[英]Using rename to safely overwrite a shared file in Linux

Here is the setup: I have a shared file (lets call it status.csv) that is read by many processes (lets call them consumers) in a read-only fashion. 这是设置:我有一个共享文件(让我们称之为status.csv),它由许多进程读取(让我们称之为消费者)以只读方式。 I have one producer that periodically updates status.csv by creating a temp file, writing data to it and using the C function discussed here: 我有一个生产者通过创建临时文件,向其写入数据并使用此处讨论的C函数定期更新status.csv:

http://www.gnu.org/software/libc/manual/html_node/Renaming-Files.html http://www.gnu.org/software/libc/manual/html_node/Renaming-Files.html

to rename the temp file (effectively overwrite) to status.csv so that the consumers can process the new data. 将临时文件(有效覆盖)重命名为status.csv,以便使用者可以处理新数据。 It want to try and guarantee (as much as possible in the Linux world) that the consumers won't get a malformed/corrupted/half-old/half-new status.csv file (I want them to get either all of the old data or all of the new). 它希望尝试并保证(尽可能在Linux世界中)消费者不会得到格式错误/损坏/半旧/半新的status.csv文件(我希望他们得到所有旧的数据或所有新的)。 I can't seem to guarantee this by reading the description of rename: it seems to guarantee that the rename action itself is atomic but I want to know if a consumer already has the status.csv file open, he will continue to read the same file as it was when it was opened, even if the file is renamed/overwritten by the producer in the middle of this reading operation. 我似乎无法通过阅读重命名的描述来保证这一点:它似乎保证重命名动作本身是原子的,但我想知道消费者是否已经打开status.csv文件,他将继续阅读相同内容文件在打开时的状态,即使文件在生成器读取操作过程中被生产者重命名/覆盖。

I attempted to prototype this thinking that the consumers will get some type of error or a half old/half new file but it seems to always be in the state it was when it was open by the consumer even if renamed/overwritten multiple times. 我试图将这种想法原型化,消费者会得到某种类型的错误或半旧/半新文件,但它似乎总是处于消费者打开的状态,即使多次重命名/覆盖也是如此。

BTW, these processes are running on the same machine (RHEL 6). 顺便说一句,这些进程在同一台机器上运行(RHEL 6)。

Thanks! 谢谢!

In Linux and similar systems, if a process has a file open and the file is deleted, the file itself remains undeleted until all processes close it. 在Linux和类似系统中,如果进程打开文件并删除文件,则文件本身将保持未删除状态,直到所有进程关闭它。 All that happens immediately is that the directory entry is deleted so that it cannot be opened again. 立即发生的所有事情是删除目录条目,以便不能再次打开它。

The same thing happens if rename is used to replace an open file. 如果使用重命名替换打开的文件,则会发生同样的情况。 The old file descriptor still keeps the old file open. 旧文件描述符仍然保持旧文件打开。 However, new opens will see the new file. 但是,新打开将看到新文件。

Therefore, for your consumers to see the new file, they must close and reopen the file. 因此,要让您的消费者看到新文件,他们必须关闭并重新打开该文件。

Note: your consumers can discover if the file has been replaced by using the stat (2) call. 注意:您的消费者可以使用stat (2)调用来发现文件是否已被替换。 If either the st_dev or st_ino entries (or both) have changed, then the file has been replaced and must be closed and reopened. 如果st_devst_ino条目(或两者)已更改,则文件已被替换,必须关闭并重新打开。 This is how tail -F works. 这就是tail -F工作原理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM