EnterCriticalSection崩溃超过64个线程

时间:2012-06-22 16:37:07

标签: c++ windows multithreading winapi

是否存在线程限制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的信号量。 我可以以某种方式改变它吗?

1 个答案:

答案 0 :(得分:1)

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

他指出问题是WaitForMultipleObjects(),它带有一个参数

  

nCount [in]

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

最大对象句柄数为MAXIMUM_WAIT_OBJECTS。这个   参数不能为零。

(来自msdn

MAXIMUM_WAIT_OBJECTSthis帖子中定义为64,更多信息。

这意味着:是的,线程数量存在硬编码限制,但限制不在EnterCriticalSection上,而是在WaitForMultipleObjects上,这会返回我应该检查的错误代码。

Here是关于如何使64个以上线程并行工作的更多信息。