c++ - 超过 64 个线程时 EnterCriticalSection 崩溃

标签 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 的信号量。 我能以某种方式改变它吗?

最佳答案

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

他指出问题是WaitForMultipleObjects(),它接受一个参数

nCount [in]

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

The maximum number of object handles is MAXIMUM_WAIT_OBJECTS. This parameter cannot be zero.

(来自 msdn)

MAXIMUM_WAIT_OBJECTS 定义为 64,更多信息请参见 this线程。

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

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

关于c++ - 超过 64 个线程时 EnterCriticalSection 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11160485/

相关文章:

c++ - 在 CodeGear C++ Builder 上有比 TMemo 更快的组件吗?

c++ - Rcpp:无法返回在循环中创建的对象

windows - 计划任务调用的批处理文件在计划时抛出错误,双击时运行正常

python - 如何向 Python 中的各个线程发送 CTRL-C 信号?

c++ - 在 std::vector::resize 和 std::vector::push_back 中摊销

c++ - 如何为某些特定数据类型重载运算符?

linux - jssc windows 和 linux

java - 在C++中模拟Java的Thread类

Java/Groovy 线程退出操作

java - 如何显示来自另一个线程的警报对话?