Vin*_*lai 6 linux filesystems tmpfs
我有一个案例,有两个进程作用于同一个文件 - 一个作为写入器,一个作为读取器。该文件是一行文本文件,编写器在循环中重写该行。读者阅读该行。伪代码如下所示:
写入程序
char buf[][18] = {
"xxxxxxxxxxxxxxxx",
"yyyyyyyyyyyyyyyy"
};
i = 0;
while (1) {
pwrite(fd, buf[i], 18, 0);
i = (i + 1) % 2;
}
Run Code Online (Sandbox Code Playgroud)
读者进程
while(1) {
pread(fd, readbuf, 18, 0);
//check if readbuf is either buf[0] or buf[1]
}
Run Code Online (Sandbox Code Playgroud)
运行这两个进程一段时间后,我可以看到readbuf是xxxxxxxxxxxxxxxxyy或yyyyyyyyyyyyyyyyxx。
我的理解是对于最大 512 字节的写入将是原子的。但从我的实验来看,原子性似乎只针对 16 个字节。
手册页没有提及任何关于普通文件的原子性,它只提到了 512 字节的管道原子性。
我已经用 tmpfs 和 ext4 尝试过,结果是相同的。使用O_SYNCext4 写入变得原子,我理解它,因为写入在到达磁盘之前不会返回,但O_SYNC对 tmpfs ( ) 没有帮助/dev/shm。
POSIX 不为管道上的写入提供任何原子操作的最低保证read(write其中最多PIPE_BUF(\xe2\x89\xa5 512) 字节的写入保证是原子性的,但读取没有原子性保证) 。read和的操作write是用字节值来描述的;除了管道之外,write与围绕单字节操作的循环相比,操作不提供额外的保证write。
我不知道 Linux 会提供任何额外的保证,无论是 16 还是 512。实际上,我希望它取决于内核版本、文件系统以及可能的其他因素,例如底层块设备、CPU 数量、CPU 架构等。
\n\n、O_SYNC和保证(同步 I/O 数据完整性完成O_RSYNC,在 POSIX 的可选SIO功能中给出和)不是您所需要的。它们保证在或系统调用之前将写入提交到持久存储,但不会对操作进行过程中启动的作出任何声明。O_DSYNCreadwritereadwritewriteread
在您的场景中,读取和写入文件看起来不像正确的工具集。
\n\nmmap如果需要的话。这并不能神奇地解决原子性问题,但可能会提高适当同步机制的性能。要执行同步,有两种基本方法:\n\nmmap+ msync)或不同的通道(例如管道)。msync)。然后,生产者将一个众所周知的值写入一个机器字( asig_atomic_t通常会起作用,尽管它的原子性仅在信号 \xe2\x80\x94\xc2\xa0 或实际上 a 上得到正式保证uintptr_t)。消费者读取该一个机器字,并且仅在该字具有可接受的值时才处理相应的数据。| 归档时间: |
|
| 查看次数: |
2625 次 |
| 最近记录: |