Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Linux文件写入页缓冲区和多线程CPU缓存_C++_Linux_Multithreading - Fatal编程技术网

C++ Linux文件写入页缓冲区和多线程CPU缓存

C++ Linux文件写入页缓冲区和多线程CPU缓存,c++,linux,multithreading,C++,Linux,Multithreading,一个线程写入FD的数据是否立即可供另一个线程使用? 下面是C++代码来解释问题。 操作系统=Red Hat Linux 文件打开代码 //Below are global variables int fileFd_A = open(fileName_A, O_RDWR | O_CREAT, S_IREAD | S_IWRITE | S_IRGRP | S_IROTH); int fileFd_B = open(fileName_B, O_RDWR | O_CREAT, S_IREAD | S_I

一个线程写入FD的数据是否立即可供另一个线程使用? 下面是C++代码来解释问题。 操作系统=Red Hat Linux

文件打开代码

//Below are global variables
int fileFd_A = open(fileName_A, O_RDWR | O_CREAT, S_IREAD | S_IWRITE | S_IRGRP | S_IROTH);
int fileFd_B = open(fileName_B, O_RDWR | O_CREAT, S_IREAD | S_IWRITE | S_IRGRP | S_IROTH);

std::atomic<int64_t> lastFileAPos = {-1};
std::atomic<int64_t> lastFileBPos = {-1};

const int WriteSz = 16;
在不同的posix线程中读取文件

//Below called in a loop (assume lastFileAPos/lastFileBPos == -1 case filtered out out before calling below)
int readSzA = pread(fileFd_A, bufferA, WriteSz, (off_t)lastFileAPos.load(std::memory_order_relaxed));
int readSzB = pread(fileFd_B, bufferB, WriteSz, (off_t)lastFileBPos.load(std::memory_order_relaxed));
现在是否有可能读线程在某些迭代中无法读取在lastFileAPos或/和lastFileBPos写入的最新数据?
i、 e readSzA readSzA 我的感觉是,由于一些写操作在写线程CPU缓存中(仍然没有发送到主存),读线程CPU可能无法立即读取它们(因此一些读取操作可能会发生) 失败)。
如果是这种情况(即某些读取可能失败),使用内存顺序释放(用于存储)和内存顺序获取(用于加载)而不是内存顺序来解决此问题吗?

i、 e.调用“lastFileAPos.load(std::memory\u order\u acquire)”将确保“lastFileAPos.store(fileAPosition,std::memory\u order\u release)”之前的所有内存写入(包括写入内核写入缓冲区)都可见。因此可以保证readSzA==WriteSz和readSzB==WriteSz

为什么要使用该文件与两个线程通信?我看不到任何好处。POSIX文件I/O的一般规则是,如果您能够证明在调用
读取
之前返回的
写入
系统调用,那么您将读取新数据:文件缓存是系统范围的,而不是每个进程/线程/CPU。这里的危险是,从理论上讲,在
write
调用之前,您的轻松存储可能会被重新排序。如果这种情况发生在现实生活中的任何系统上,我都会感到惊讶:编译器无法对其不知道其工作原理的函数重新排序访问,系统调用陷阱应该是一种有效的内存屏障。但是,是的,使用release/acquire语义甚至可以避免任何理论问题。它们在内核的缓冲区/页面缓存上有某种类型的锁,具有获取/释放障碍,因此下一个获取锁的进程可以确保看到在前一个进程释放锁之前写入的所有数据。这不是“跳过写入CPU缓存”的问题——大多数系统都有一致的缓存,所以这不是问题所在,而是在加载和存储首先命中缓存之前对其进行重新排序。(内存排序问题主要与缓存有关,这似乎是一个常见的误解。)可以肯定的是,任何现代类Unix系统在读/写方面都会有这种行为,不管它是否声称完全符合POSIX。否则,系统将无法使用。
//Below called in a loop (assume lastFileAPos/lastFileBPos == -1 case filtered out out before calling below)
int readSzA = pread(fileFd_A, bufferA, WriteSz, (off_t)lastFileAPos.load(std::memory_order_relaxed));
int readSzB = pread(fileFd_B, bufferB, WriteSz, (off_t)lastFileBPos.load(std::memory_order_relaxed));