.NET垃圾收集,C ++ / CLI interior_ptr和线程安全

时间:2012-05-19 21:19:23

标签: .net pointers garbage-collection thread-safety c++-cli

所以我理解interior_ptr<typename>可以用于使用fixed语句完全与C♯中的结构数组一起操作,但它不会修复堆上的数组并允许垃圾回收移动它。这很好,因为我不想阻止垃圾收集器有效地工作。但是,垃圾收集器在一个单独的线程上运行,当它处于活动状态时,所有其他线程在堆上的对象被压缩时停止。

假设我有以下代码:

interior_ptr<unsigned char> sourceBufferPtr = reinterpret_cast<interior_ptr<unsigned char>>(&sourceBuffer[0]) + sourceOffset;

代码应该像这样运行,例如:

  1. &sourceBuffer[0]返回数组中第一项的地址:32。
  2. sourceOffset:8。
  3. reinterpret_cast<interior_ptr<unsigned char>>(&sourceBuffer[0])将地址转换为interior_ptr<unsigned char>,并将其添加到sourceOffset
  4. sourceBufferPtr应该等于......
    • 40如果垃圾收集器没有移动阵列。
    • 24如果垃圾收集器将阵列移动到16位置。
    • 如果垃圾收集器在步骤3和4之间移动数组,则
    • 为40,因此在步骤3之后阵列的位置将更新为16,但分配给sourceBufferPtr的结果仍为40。
  5. 我是否正确假设垃圾收集器可以在步骤3和4之间停止线程并可能将错误的值分配给sourceBufferPtr或者公共语言运行时以某种方式知道如何确保整个语句的原子/值是否正确? interior_ptr<typename> 的安全性是什么?

1 个答案:

答案 0 :(得分:3)

  

我是否认为垃圾收集器可以阻止垃圾收集器   步骤3和4之间的线程可能会分配错误的值   sourceBufferPtr?

是的,因为您的代码不正确。通过使用reinterpret_cast 获取到数组元素的无错指针后,您将为GC引入一个使窗口无效的机会窗口。您需要像这样不间断地使用interior_ptr:

interior_ptr<unsigned char> bufferPtr = &sourceBuffer[0];
interior_ptr<unsigned char> sourceBufferPtr = bufferPtr + sourceOffset;

在这个新代码中,只有interior_ptr。即使是第二项任务右侧的临时项也是一个interior_ptr。