c++ - mmap共享缓冲区读取问题

标签 c++ c linux mmap cpu-cache

我有一个内核模块分配了一个大的内存缓冲区,然后这个缓冲区被映射到用户空间。
该模块从硬件接收一些数据,然后将新数据放入缓冲区,并在其前面加上一个标志。 (内存初始化为0,flag为1)。

用户空间程序在返回指向有效数据的指针之前循环读取标志

代码的简化版本:

uint8_t * getData()
{
    while(1)
   {
      if(*((volatile uint32_t*)this->buffer) == 1)
          return this->buffer+sizeof(uint32_t);
   }
}

内存区域被映射为共享,并且完整的缓冲区内存转储确认缓冲区被正确写入。

问题是在一定数量的正确读取之后,这个函数停止返回。
这可能是由于 CPU 缓存造成的吗?有没有一种方法可以避免这种情况并确保每次都直接从 RAM 而不是从缓存中进行读取?

最佳答案

是的,这可能是由于读取器端的 CPU 缓存所致。有人可能认为“volatile”关键字应该可以防止此类问题,但这种说法并不完全正确,因为 volatile 只是指示编译器不要注册变量,与指示 cpu 直接从主内存读取不完全相同每次。

问题需要在写端解决。根据您的描述,这听起来像是写入发生在内核模块中并从用户端读取。如果这两个操作发生在不同的 cpu(不同的缓存域)上,并且没有任何东西可以在读取端触发缓存失效,那么您将像您描述的那样卡在读取端。您需要在存储指令后强制在 linux 内核上刷新存储缓冲区。假设它是 linux 内核,在设置标志和模块中的值后立即插入对 smp_mb 的调用很可能在所有架构上都做正确的事情。

关于c++ - mmap共享缓冲区读取问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9185803/

相关文章:

c++ - 我的 C++ makefile 无法为每个 .cpp 代码创建目标文件

c++ - C/C++ 的 MC/DC 覆盖工具

c++ - 转换一个由迭代器指向的对象

c - 访问另一个进程中的共享内存缓冲区

c - C Mandelbrot 程序中的二进制错误导致无效操作数

linux - 附加到 GNU screen ,然后执行命令

c++ - cv-qualified 是什么意思?

c - 加密程序交换?

c - 需要从删除空格和字母的字符串中获取多个数字输入

linux - 在 linux 命令参数中添加\之前的 $