我有一个巨大的数组,由两个线程进行不同的分析:
因此,每个线程看起来像这样:
unsafe void Thread(UInt16[] data)
{
fixed(UInt16* pData = data)
{
UInt16* pDataEnd = pData + data.Length;
for(UInt16* pCur=pData; pCur != pDataEnd; pCur++)
{
// do stuff
}
}
}
由于没有互斥(故意),我想知道在并行线程的相同数据上使用两个修复语句是否安全?大概第二个修复应该返回与第一个相同的指针,因为内存已被固定...当第一个完成时,它不会真正解除内存,因为还有第二个fixed()仍处于活动状态..有没有人试过这个方案
答案 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编译器消除了边界检查。所以不需要不安全的代码。
请注意,如果您的访问模式比这更复杂,则不会成立。