读取访问后内存映射文件值设置为零

Memory mapped file value is set to zero after read access

我想在 Python 和 C# 之间实现进程间通信,以便在我的 C# 应用程序中读取由 Python 脚本编写的值。 在 C# 中,我使用 MemoryMappedFile class:

MemoryMappedFile mmfSimPro = MemoryMappedFile.CreateOrOpen("MyFileMappingObject_SimPro", 20);
MemoryMappedViewAccessor accessorAxesSimPro = mmfSimPro.CreateViewAccessor(0, 20);
for (int i = 0; i < axesSimPro.Length; i++)
   axesSimPro[i] = accessorAxesSimPro.ReadSingle(sizeof(float) * i);

它成功读取了值,但之后它将内存映射文件中的值设置为零。因此,如果我再次读取内存映射文件(并且它还没有被 Python 脚本覆盖),我将只读取零。我怎样才能防止这种情况发生?

我的 python 脚本如下所示:

def WriteAxes():
  shmem = mmap.mmap(0,256, "MyFileMappingObject_SimPro",mmap.ACCESS_WRITE)
  struct.pack_into('f',shmem,0,_ctrl.Joints[1].CurrentValue)
  struct.pack_into('f',shmem,4,_ctrl.Joints[0].CurrentValue)
  struct.pack_into('f',shmem,8,_ctrl.Joints[2].CurrentValue)
  struct.pack_into('f',shmem,12,_ctrl.Joints[3].CurrentValue)
  struct.pack_into('f',shmem,16,_ctrl.Joints[4].CurrentValue-90)
  shmem.close()

因为您使用的是 .CreateOrOpen,所以您使用的是 Non-Pesisted MemoryMappedFile(参见 https://msdn.microsoft.com/en-us/library/dd997372(v=vs.110).aspx这意味着 GC 可以自由地对内容进行 GC

我正在对你的其余代码做一些假设,但看起来你 CreateOrOpen 并在一个方法中读取,因此 GC 可以在你完成阅读后立即自由处理内容,基本上这是一些您的 C# 应用程序拥有的内存,它将照常进行 GC。

您需要在 A 的更广泛的上下文中 .CreateOrOpen(即它在应用程序启动时或在任何适当的 'session' 对象中打开(并保持引用))或移动到 .CreateFromFile 将其视为持久性(如果需要/适当,可能在开始时进行一些手动清零)。

TLDR; mmfSimPro 可能应该保存在应用程序/class 级别的字段中,而不是在局部变量中,因此它具有应用程序/class 生命周期的实时 GC 句柄,而不仅仅是长度读取方法。