gpt4 book ai didi

c - write() 返回后立即从文件中读取() 是否安全?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:31:53 24 4
gpt4 key购买 nike



我有一个非常具体的应用程序,我需要一个具有持久存储的自动增量变量。

准确地说,我将 int 变量的十进制表示形式存储在一个文件中。为了生成下一个数字,我从文件中 read(),将内容转换回 int,加 1 和 write() 返回文件。我不需要并发访问这些数据。只有来自一个进程的一个线程调用函数来检索自动递增数。该程序在嵌入式环境中运行,没有人可以访问控制台,因此安全性不应该是一个问题。如果重要的话,它可以在 MIPS 上的 Linux 2.6.24 上运行。
问题是,我没有得到 100% 可重现的结果。有时我会收到重复的数字,这对我的申请来说是 Not Acceptable 。

我的实现如下。

在启动应用程序时,我有:

int fd = open("myfile", O_RDWR|O_CREAT|O_SYNC, S_IRWXU|S_IRWXG|S_IRWXO);

自增函数:

int get_current(int fd)
{
char value[SIZE];
lseek(fd, 0, SEEK_SET);
read(fd, value, SIZE);
return atoi(value);
}

int get_next(int fd)
{
char value[SIZE];
int cur = get_current(fd);
memset(value, 0, SIZE);
sprintf(value, "%d", cur + 1);
lseek(fd, 0, SEEK_SET);
write(fd, value, SIZE);
//fsync(fd); /* Could inserting this be the solution? */
return (cur + 1);
}

为了代码的可读性,我特意省略了上面的错误检查。我有代码来检查所有系统调用的返回值。

代码本来是别人写的,现在发现了这个问题,解决的第一步就是找出是什么原因造成的。我担心这可能与缓存文件访问的方式有关。我知道当我 write() 时,我无法保证数据确实到达了物理介质,但是调用 read() 而不调用 fsync 是否安全() 并仍然得到可预测的结果?如果是,那我就没主意了;)

感谢您通读。

最佳答案

是的,写入后立即阅读是安全的。在类 Unix 系统中,当 write() 返回时,数据安全地位于内核缓冲池中,并将返回给需要读取数据的其他进程。类似的注释适用于使用 O_SYNC、O_DSYNC、O_FSYNC(确保数据写入磁盘)和 Windows 系统。显然,当 aio_write() 调用返回时,异步写入不会完成,但会在发出完成信号时完成。

但是,您的问题出现了,因为您不能确保一次有一个进程或线程访问该文件。您必须确保获得串行访问,这样您就不会同时从文件读取两个进程(或线程)。这是 DBMS 术语中的“丢失更新”问题。

您需要确保一次只有一个进程可以访问。如果您的进程合作,您可以使用建议锁定(通过 POSIX 系统上的 fcntl())。如果您的流程不合作,或者您不确定,您可能需要进行强制锁定,或者完全使用其他一些技术。

关于c - write() 返回后立即从文件中读取() 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4486563/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com