【问题标题】:.NET Garbage Collection, C++/CLI interior_ptr, and Thread Safety.NET 垃圾收集、C++/CLI internal_ptr 和线程安全
【发布时间】:2012-05-26 23:45:56
【问题描述】:

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

假设我有以下代码:

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

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

  1. &amp;sourceBuffer[0] 返回数组中第一项的地址:32。
  2. sourceOffset: 8.
  3. reinterpret_cast&lt;interior_ptr&lt;unsigned char&gt;&gt;(&amp;sourceBuffer[0]) 将地址转换为 interior_ptr&lt;unsigned char&gt;,然后添加到 sourceOffset
  4. sourceBufferPtr 应该等于……
    • 如果垃圾收集器没有移动数组,则为 40。
    • 如果垃圾收集器将数组移动到 16 之类的位置,则为 24。
    • 如果垃圾收集器在第 3 步和第 4 步之间移动了数组,则数组的位置将在第 3 步之后更新为 16,但分配给 sourceBufferPtr 的结果仍为 40。

我是否正确假设垃圾收集器可以在步骤 3 和 4 之间停止线程并可能将错误的值分配给 sourceBufferPtr 或者公共语言运行时以某种方式知道如何确保整个语句是原子/值是否正确?使用interior_ptr&lt;typename&gt; 做什么安全的?

【问题讨论】:

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


    【解决方案1】:

    我是否正确假设垃圾收集器可以停止 步骤 3 和 4 之间的线程,并可能分配错误的值 sourceBufferPtr?

    是的,因为您的代码不正确。通过使用 reinterpret_cast 在获得指向数组元素的未管理指针后,您为 GC 引入了使指针无效的机会窗口。您需要像这样不间断地使用interior_ptr:

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

    在这个新代码中,只有interior_ptr。甚至第二个赋值右侧的临时变量也是一个 internal_ptr。

    【讨论】:

    • 好吧,在考虑了 C++/CLI 规范之后,将缓冲区分配给 pin_ptr&lt;T&gt; sourceBufferPtr 以使其保持固定,然后执行任何算术将结果分配给各种 interior_ptr&lt;unsigned char&gt; 变量是有意义的最后将sourceBufferPtr 设置为nullptr 以取消固定它。短跨度可以让我确保指针值保持有效,并且在短时间内发生垃圾收集的可能性几乎为零。
    • 可以,但我提供的代码已经安全了。编译器确保编译这是一种不会引入与 GC 竞争的方式。请参阅此处的示例:msdn.microsoft.com/en-us/library/y0fh545k(v=vs.80).aspx 查看 IL,地址获取操作已返回“托管指针”。
    • 具有讽刺意味的是,我发现自己无论如何都在固定指针。在混合本机/托管模式下使用 C++/CLI,我可以通过使用内部函数更快地处理大量数据。此处示例:social.msdn.microsoft.com/Forums/en/vclanguage/thread/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 1970-01-01
    相关资源
    最近更新 更多