多线程'固定'

时间:2012-04-12 18:46:16

标签: c# multithreading memory parallel-processing fixed

我有一个巨大的数组,由两个线程进行不同的分析:

  • 数据很大 - 不允许复制
  • 线程必须同时处理
  • 必须禁用边界检查以获得最佳性能

因此,每个线程看起来像这样:

unsafe void Thread(UInt16[] data)
{
  fixed(UInt16* pData = data)
  {
    UInt16* pDataEnd = pData + data.Length;
    for(UInt16* pCur=pData; pCur != pDataEnd; pCur++)
    {
      // do stuff
    }
  }
}

由于没有互斥(故意),我想知道在并行线程的相同数据上使用两个修复语句是否安全?大概第二个修复应该返回与第一个相同的指针,因为内存已被固定...当第一个完成时,它不会真正解除内存,因为还有第二个fixed()仍处于活动状态..有没有人试过这个方案

3 个答案:

答案 0 :(得分:2)

根据“CLR via C#”,这样做是安全的。

编译器在pData变量上设置'固定'标志(在指针上,而不是在数组实例上)。

所以多次/递归使用应该没问题。

答案 1 :(得分:1)

也许不使用固定,你可以使用GCHandle.Alloc来固定数组:

// not inside your thread, but were you init your shared array
GCHandle handle = GCHandle.Alloc(anArray, GCHandleType.Pinned);
IntPtr intPtr = handle.AddrOfPinnedObject();


// your thread
void Worker(IntPtr pArray)
{
  unsafe
  {
     UInt16* ptr = (UInt16*) pArray.ToPointer();
      ....
  }
}        

答案 2 :(得分:1)

如果你需要做的只是

 for(int i = 0; i < data.Length; i++)
 {
     // do stuff with data[i]
 }

JIT编译器消除了边界检查。所以不需要不安全的代码。

请注意,如果您的访问模式比这更复杂,则不会成立。