0

EnterCriticalSection() 是否有线程限制?以下代码适用于 64 个线程,但在使用 65 个或更多线程时会崩溃:

CRITICAL_SECTION TestCritSection;

unsigned int threadId;

int getThreadId()
{
    int tid = -1;

    EnterCriticalSection(&TestCritSection);

    tid= threadId;
    threadId++;

    LeaveCriticalSection(&TestCritSection);

    return tid;
}

void parallelTest()
{
    int tid = getThreadId();
    cout << "Thread " << tid << " executed" << endl;
}


void
multiThreadTest()
{
    unsigned int numThreads = 64; // fine, but program crashes when numThreads is set to 65 or more
    HANDLE *threads = new HANDLE[numThreads];
    DWORD ThreadID;
    threadId = 1;

    if (!InitializeCriticalSectionAndSpinCount(&TestCritSection, 0x00000400)) return;

    for (int i=0; i<numThreads; ++i)
    {
        threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) parallelTest, (LPVOID) NULL, 0, &ThreadID);
    }

    WaitForMultipleObjects(numThreads, threads, TRUE, INFINITE);

    DeleteCriticalSection(&TestCritSection);

    for (int i=0; i<numThreads; ++i)
    {
        CloseHandle(threads[i]);
    }

    delete [] threads;
}

我猜 CRITICAL_SECTION 在内部使用最大计数为 64 的信号量。我能以某种方式改变它吗?

4

1 回答 1

1

由于没有人愿意回答我的问题,我将根据 HansPassant 对我的问题的评论自己回答。

他指出问题是WaitForMultipleObjects(),它需要一个参数

nCount [in]

The number of object handles in the array pointed to by lpHandles.

对象句柄的最大数量是 MAXIMUM_WAIT_OBJECTS。此参数不能为零。

(来自msdn

MAXIMUM_WAIT_OBJECTS被定义为 64,更多信息在这个线程中。

这意味着:是的,线程数量有硬编码限制,但限制不是 onEnterCriticalSection而是 on WaitForMultipleObjects,它返回一个我应该检查的错误代码。

以下是有关如何让超过 64 个线程并行工作的更多信息。

于 2012-06-26T10:13:33.180 回答