全部。我需要在 c# 代码中使用 winapi 关键部分。
首先,我导入函数:
[StructLayout(LayoutKind.Sequential)]
public struct CRITICAL_SECTION { public int dummy; }
// INIT CRITICAL SECTION
[DllImport("kernel32.dll")]
static extern bool InitializeCriticalSectionAndSpinCount(ref CRITICAL_SECTION
lpCriticalSection, uint dwSpinCount);
// DELETE CRITICAL SECTION
[DllImport("kernel32.dll")]
static extern void DeleteCriticalSection(ref CRITICAL_SECTION
lpCriticalSection);
// ENTER CRITICAL SECTION
[DllImport("kernel32.dll")]
static extern void EnterCriticalSection(ref CRITICAL_SECTION
lpCriticalSection);
// LEAVE CRITICAL SECTION
[DllImport("kernel32.dll")]
static extern void LeaveCriticalSection(ref CRITICAL_SECTION
lpCriticalSection);
通过这种方式,我尝试使用临界区:
static void Main(string[] args)
{
GenerateArray();
InvokeThread invokeThread = () =>
{
WaitForSingleObject(ghSemaphore, 0);
EnterCriticalSection(ref CriticalSection); // critical section
int[] array = new int[ARRAY_SIZE_PER_THREAD];
int baseI = thread * ARRAY_SIZE_PER_THREAD;
for (int i = 0; i < ARRAY_SIZE_PER_THREAD; ++i)
{
array[i] = gList[baseI + i];
}
LeaveCriticalSection(ref CriticalSection); // critical section
ReleaseSemaphore(ghSemaphore, 1, IntPtr.Zero);
return 0;
};
ghSemaphore = CreateSemaphore(ref seqAttr, THREADS_NUMBER, THREADS_NUMBER, "");
InitializeCriticalSectionAndSpinCount(ref CriticalSection, 0);
IntPtr threadPtr = Marshal.GetFunctionPointerForDelegate(invokeThread);
IntPtr[] handlers = new IntPtr[THREADS_NUMBER];
for (int i = 0; i < THREADS_NUMBER; ++i)
{
int handle = CreateThread(IntPtr.Zero, 0, threadPtr, IntPtr.Zero, 0, 0);
handlers[i] = new IntPtr(handle);
}
WaitForMultipleObjects(THREADS_NUMBER, handlers, true, Infinite);
DeleteCriticalSection(ref CriticalSection); // delete critical section
}
}
但在下一行 gList 包含错误的值。如果我不使用关键部分,每件事都很好。
for (int i = 0; i < ARRAY_SIZE_PER_THREAD; ++i)
{
array[i] = gList[baseI + i];
}
哪里可能有问题?