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

标签 .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。
    • 如果垃圾收集器将数组移动到 16 这样的位置,则为 24。
    • of 40 如果垃圾收集器在第 3 步和第 4 步之间移动数组,那么在第 3 步之后数组的位置将更新为 16,但结果分配给 sourceBufferPtr仍然是 40 岁。

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

最佳答案

Am I correct to assume that the garbage collector could stop the thread between steps 3 and 4 and possibly assign the wrong value to sourceBufferPtr?

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

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

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

关于.NET 垃圾收集、C++/CLI interior_ptr 和线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10668931/

相关文章:

java - 并发标记和清除算法详细信息

.net - 为什么 2 个 Try/Catch block 会卡住应用程序?

c# - 如何循环读取文件的每一行?

.net - TabControl 标题的高度

c - 我找不到导致间歇性崩溃的指针错误。你可以吗?

Java:对象池和哈希集

c# - WPF webbrowser 的 LoadCompleted 事件

c - 调试 C 代码和指针

c++ - 智能指针无法释放内存

c# - 检测内存何时在外部 .NET 进程中移动?