.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]
返回数组中第一项的地址:32sourceOffset
:8reinterpret\u cast(&sourceBuffer[0])
将地址强制转换为interior\u ptr
,该地址被添加到sourceOffset
sourceBufferPtr
应等于…
- 40,如果垃圾收集器未移动阵列
- 24如果垃圾收集器将阵列移动到类似16的位置
- 如果垃圾收集器在步骤3和步骤4之间移动阵列,则该阵列的位置将在步骤3之后更新为16,但分配给
的结果仍然是40sourceBufferPtr
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,我可以更快地处理大量数据。示例如下: