它是安全的,尽快从文件中读取()作为write()返回? [英] Is it safe to read() from a file as soon as write() returns?

查看:182
本文介绍了它是安全的,尽快从文件中读取()作为write()返回?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




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



要precise,我存储在一个文件中的 INT 变量的小数重presentation。要生成的下一个数字,我阅读()从文件,转换的内容回 INT ,加1 的write()回文件。我不需要这个数据的并发访问。只有从一个过程中的一个线程调用函数检索自动递增数。该方案在嵌入式环境中,没有人将有权访问的控制台上运行,所以安全性不应该是一个问题。如果它的事项,它运行在MIPS上的Linux 2.6.24。


问题是,我没有得到100%可重复的结果。有时候,我得到重复的数字,这是我的应用程序不能接受的。



我的实现如下。



在启动应用程序,我有:



I have a very specific application where I need an auto-increment variable with persistent storage.

To be precise, I store the decimal representation of an int variable on a file. To generate the next number, I read() from the file, convert the contents back to int, add 1 and write() back to the file. I do NOT need concurrent access to this data. Only one thread from one process calls the functions to retrieve the auto-increment number. The program runs on an embedded environment, where no-one will have access to the console, so security should not be a concern. If it matters, it runs on Linux 2.6.24 on MIPS.
The problem is, I am not getting 100% reproducible results. Sometimes I get repeated numbers, which is unacceptable for my application.

My implementation is as follows.

On starting the application, I have:

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);
}

我特意留下了上面的错误检查code可读性的缘故。我在地方code,检查所有的系统调用的返回值。



在code最初是由另外一个人写的,而现在,我已经发现这个问题,首先要解决它要找出可能造成它。我担心它可能与文件访问被缓存的方式。我知道当我的write()我不出示担保数据有史以来居然达到了物理介质,但是它安全地调用阅读(),而不必名为 FSYNC(),仍然可以得到predictable结果?如果是,那么我的想法;)



感谢您阅读过。

I have intentionally left out error checking above for the sake of code readability. I have code in place to check return values of all syscalls.

The code was originally written by another person, and now that I have detected this problem, the first step to solve it is to find out what could have caused it. I am concerned that it could be related to the way file accesses are cached. I know when I write() I have no gurantee the data ever actually reached the physical medium, but is it safe to call read() without having called fsync() and still get predictable results? If it is, then I'm out of ideas ;)

Thanks for reading through.

推荐答案

是的,它是安全的写入后立即读取。在类Unix系统中,数据安全是在内核缓冲池时,的write()回报,将退还给需要读取数据的其它进程。类似的评论使用O_SYNC,O_DSYNC,O_FSYNC(这确保数据写入到磁盘)时应用和Windows系统。显然,异步写入将是不完整的则aio_write()调用返回的时候,但是当完成时暗示,将完成。

Yes, it is safe to read immediately after writing. In a Unix-like system, the data is safely in the kernel buffer pool when a write() returns and will be returned to other processes that need to read the data. Similar comments apply when using O_SYNC, O_DSYNC, O_FSYNC (which ensure that data is written to disk) and to Windows systems. Clearly, an asynchronous write will not be complete when the aio_write() call returns, but it will be complete when the completion is signalled.

不过,你的问题就出现了,因为你没有确保你有一个单一的进程或线程访问文件在同一时间。您的必须的确保您获得串行访问,这样你没有得到两个进程(或线程)在同一时间从文件中读取。这是DBMS条款丢失更新的问题。

However, your problem arises because you are not ensuring that you have a single process or thread accessing the file at a time. You must ensure that you get serial access so that you don't get two processes (or threads) reading from the file at the same time. This is the 'lost update' problem in DBMS terms.

您需要确保只有一个进程在同一时间访问。如果你的流程合作,则可以使用建议锁(通过的fcntl()的POSIX系统)。如果你的进程不配合,或者你不知道,你可能需要去强制锁定,或者完全采用其他技术。

You need to ensure that only one process has access at a time. If your processes cooperate, you can use advisory locking (via fcntl() on POSIX systems). If your processes don't cooperate, or you're not sure, you may need to go for mandatory locking, or use some other technique altogether.

这篇关于它是安全的,尽快从文件中读取()作为write()返回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆