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

.NET垃圾收集,C++/CLI内部线程和线程安全,.net,pointers,garbage-collection,thread-safety,c++-cli,.net,Pointers,Garbage Collection,Thread Safety,C++ Cli,所以我知道interior\u ptr可以像在C中一样使用结构数组进行操作♯ 使用fixed语句,但它不会修复堆上的数组,而是让垃圾回收将其移动。这很好,因为我不想妨碍垃圾收集器有效地工作。但是,垃圾收集器在单独的线程上运行,当它处于活动状态时,堆上的对象被压缩时,所有其他线程都将停止 假设我有以下代码: interior_ptr<unsigned char> sourceBufferPtr = reinterpret_cast<interior_ptr<unsigned

所以我知道
interior\u ptr
可以像在C中一样使用结构数组进行操作♯ 使用
fixed
语句,但它不会修复堆上的数组,而是让垃圾回收将其移动。这很好,因为我不想妨碍垃圾收集器有效地工作。但是,垃圾收集器在单独的线程上运行,当它处于活动状态时,堆上的对象被压缩时,所有其他线程都将停止

假设我有以下代码:

interior_ptr<unsigned char> sourceBufferPtr = reinterpret_cast<interior_ptr<unsigned char>>(&sourceBuffer[0]) + sourceOffset;
interior\u ptr sourceBufferPtr=reinterpret\u cast(&sourceBuffer[0])+sourceOffset;
代码应如下运行,例如:

  • &sourceBuffer[0]
    返回数组中第一项的地址:32
  • sourceOffset
    :8
  • reinterpret\u cast(&sourceBuffer[0])
    将地址强制转换为
    interior\u ptr
    ,该地址被添加到
    sourceOffset
  • sourceBufferPtr
    应等于…
    • 40,如果垃圾收集器未移动阵列
    • 24如果垃圾收集器将阵列移动到类似16的位置
    • 如果垃圾收集器在步骤3和步骤4之间移动阵列,则该阵列的位置将在步骤3之后更新为16,但分配给
      sourceBufferPtr
      的结果仍然是40
  • 假设垃圾收集器可以在步骤3和步骤4之间停止线程,并可能将错误的值分配给
    sourceBufferPtr
    ,这是否正确?或者公共语言运行库是否知道如何确保整个语句是原子的/值是正确的?使用
    内饰\u ptr
    什么是安全的

    我假设垃圾收集器可以停止垃圾收集,对吗 在步骤3和步骤4之间执行线程,并可能将错误的值指定给 sourceBufferPtr

    是的,因为您的代码不正确。通过在获得指向数组元素的未更改指针后使用reinterpret_cast,您为GC引入了使指针无效的机会窗口。您需要在不中断的情况下使用interior_ptr,如下所示:

    interior_ptr<unsigned char> bufferPtr = &sourceBuffer[0];
    interior_ptr<unsigned char> sourceBufferPtr = bufferPtr + sourceOffset;
    
    interior_ptr bufferPtr=&sourceBuffer[0];
    内部\u ptr sourceBufferPtr=bufferPtr+sourceOffset;
    

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

    好吧,在考虑了C++/CLI规范之后,将缓冲区分配给
    pin_ptr sourceBufferPtr
    以保持其固定是有意义的,然后执行任何算法,将结果分配给各种
    interior_ptr
    变量,最后将
    sourceBufferPtr
    设置为
    nullptr
    以取消固定。短时间跨度将允许我确保指针值保持有效,并且在短时间内发生垃圾收集的可能性几乎为零。这将起作用,但我给出的代码已经是安全的了。编译器确保编译这是一种不会引入与GC竞争的方式。请看下面的例子:查看IL地址获取操作已经返回了一个“托管指针”。讽刺的是,我发现自己还是在固定指针。在混合本机/托管模式下使用C++/CLI,通过使用intrinsic,我可以更快地处理大量数据。示例如下: