C++ Linux pread的使用是否避免了;数据不可用,无法读取由不同线程写入的数据;?
请假设以下场景(OS=Redhat Linux) 选项A: 写入线程:使用FD=1写入文件。设置std::原子变量中最后写入的位置和大小 编辑以更清晰:使用write C函数调用完成写操作。 读卡器线程:在上述std::原子变量中保存的值处,使用不同的FD=2读取上述文件 然后,我假设,在读线程之上,可能无法读取写入线程写入的所有数据(即,FD=2的读调用可能返回较少的字节数)。因为FD级别可能有缓冲 ====================================================================================== 选项B: 写入线程:使用FD=1写入文件。设置std::原子变量中最后写入的位置和大小 编辑以使其更清晰:仅追加完成(无覆盖发生)。使用write C函数调用完成写入。 读卡器线程:使用保存在上述std::原子变量中的相同FD=1读取(使用pread)上述文件C++ Linux pread的使用是否避免了;数据不可用,无法读取由不同线程写入的数据;?,c++,c,linux,multithreading,C++,C,Linux,Multithreading,请假设以下场景(OS=Redhat Linux) 选项A: 写入线程:使用FD=1写入文件。设置std::原子变量中最后写入的位置和大小 编辑以更清晰:使用write C函数调用完成写操作。 读卡器线程:在上述std::原子变量中保存的值处,使用不同的FD=2读取上述文件 然后,我假设,在读线程之上,可能无法读取写入线程写入的所有数据(即,FD=2的读调用可能返回较少的字节数)。因为FD级别可能有缓冲 ==============================================
现在,是否保证写入线程写入的所有数据都由读线程读取?缓冲处于
libc
级别,在将数据移交给内核之前保留数据pread
是一个系统调用,它只提供已经显示给内核的数据
因此,没有。pread
为您节省了对seek+read的额外调用,它不能解决任何缓冲问题
如何确保内核能够看到您的数据?您还没有显示写入程序代码,但通常调用
fflush
就可以了。如果读线程偷看原子中的值,但就在它从其FD读取之前,写入程序线程进入并执行另一个I/O操作,会怎么样?如果执行fflush
(如正确答案中所述),使用哪种文件描述符并不重要:它们连接到相同的inode和页面缓存中的相同页面。只有内部的libc缓冲区是分开的,所以这就是需要显式刷新的地方。@无用,如果不清楚,很抱歉。使用写C函数调用完成写操作,因此,fflush与本案无关。我已经编辑了问题。如果不清楚,很抱歉。使用写C函数调用完成写操作,因此,fflush与本案无关。我已经编辑了这个问题。然后你可能还想澄清你所说的“FD级缓冲”是什么意思。一旦内核获取了您的数据,它将为每个人维护一个一致的视图,无论它是在RAM中还是写入磁盘。写入可能不是瞬时的和原子的(部分写入?EINTR?),但使用pread
也不能解决这一问题。我所说的“FD级缓冲”是,我认为(只是一种推测),当为特定的FD编写写调用时,内核可能会在FD级别维护一个缓冲区。我提到的原子变量只有在写入成功时才会更新(即存储了写入的位置和写入的数据大小)。这样您就可以放心了。每个FD内核级别的缓冲将使相同的数据通过某些系统调用而不是其他系统调用可见,这不是一件事。这是否意味着上述选项a和选项B都可以保证读卡器线程中所有数据的可用性?