c++ - 最大用户模式调度程序线程数

标签 c++ c multithreading windows-server-2012-r2

我正在编写用于管理大量 UMS 工作线程的 UMS 调度程序,我遇到了一个非常奇怪的问题。由于某种原因,我可以创建的最大 UMS 线程数是 8192(普通线程没有这样的问题,我可以轻松创建 >20 000 个线程)。

调用CreateRemoteThreadEx返回的错误是1450“系统资源不足”

PC配置如下:

  • Windows Server 2012R2 数据中心 x64
  • 16GB 或内存
  • 2 个英特尔至强 5520 处理器
  • 1TB 磁盘空间

我尝试了以下方法:

  1. 增加流程工作集(无效果)
  2. 通过注册表增加 SystemPages 的数量(没有效果,现在设置为 0)
  3. 我已经检查了可用页面、非分页和分页池的限制(在 CreateRemoteThreadEx 调用期间没有一个处于饥饿状态)
  4. 我已经在另一台 PC 上试过了(2GB 内存、Inter Core 2 Duo 处理器、Windows 8.1x64,得到了相同的魔数(Magic Number) 8192)。

这里是一个代码示例来测试:

DWORD
UmsThreadRoutine(
    PVOID pState
)
{
    UNREFERENCED_PARAMETER(pState);
    return 0;
};

int main(int args, char **argv)
{
    PCHAR pMessage = "Program End";
    DWORD dwErrorCode = ERROR_SUCCESS;
    DWORD dwIteration = 0;
    PUMS_COMPLETION_LIST pUmsCompletionList = NULL;
    if (!::CreateUmsCompletionList(&pUmsCompletionList))
    {
        pMessage = "CreateUmsCompletionList";
        goto EXIT_POINT;
    }

    for (int i = 0; i < 20000; ++i)
    {
        dwIteration = i;
        LPPROC_THREAD_ATTRIBUTE_LIST pAttributes = NULL;
        SIZE_T szAttributes = 0;

        if (::InitializeProcThreadAttributeList(NULL, 1, 0, &szAttributes))
        {
            pMessage = "InitializeProcThreadAttributeList(Size)";
            goto EXIT_POINT;
        }

        pAttributes = (LPPROC_THREAD_ATTRIBUTE_LIST)::malloc(szAttributes);
        if (pAttributes == NULL)
        {
            pMessage = "malloc";
            goto EXIT_POINT;
        }
        if (!::InitializeProcThreadAttributeList(pAttributes, 1, 0, &szAttributes))
        {
            pMessage = "InitializeProcThreadAttributeList";
            goto EXIT_POINT;
        }

        PUMS_CONTEXT pUmsContext = NULL;
        if (!::CreateUmsThreadContext(&pUmsContext))
        {
            pMessage = "CreateUmsThreadContext";
            goto EXIT_POINT;
        }

        UMS_CREATE_THREAD_ATTRIBUTES umsCreationAttributes = { UMS_VERSION, pUmsContext, pUmsCompletionList };
        if (!::UpdateProcThreadAttribute(pAttributes, 0, PROC_THREAD_ATTRIBUTE_UMS_THREAD, &umsCreationAttributes, sizeof(UMS_CREATE_THREAD_ATTRIBUTES), NULL, NULL))
        {
            pMessage = "UpdateProcThreadAttribute";
            goto EXIT_POINT;
        }

        DWORD dwId = 0;
        HANDLE hThread = ::CreateRemoteThreadEx(
            ::GetCurrentProcess(),
            NULL,
            0,
            (LPTHREAD_START_ROUTINE)::UmsThreadRoutine,
            NULL,
            CREATE_SUSPENDED,
            pAttributes,
            &dwId
        );
        if (hThread == NULL)
        {
            pMessage = "CreateRemoteThreadEx";
            goto EXIT_POINT;
        }

        ::DeleteProcThreadAttributeList(pAttributes);
    }

    EXIT_POINT:
    dwErrorCode = ::GetLastError();
    ::printf("Program exited with Error Code '%d' on step '%s' on iteration '%d'", dwErrorCode, pMessage, dwIteration);
}

我在另一台 PC 上运行此代码段并且运行良好(我创建了 20000 个 UMS 线程)。

电脑配置:

  • Windows 8.1 企业版 x64
  • 英特尔酷睿 i5-3470
  • 8 GB 内存
  • 1 TB 的可用空间。

所以基本上这看起来像是某种限制(并且看起来可以更改)。

你有什么想法吗?

更新:在盒子上安装最新更新后,一切都没有改变。

最佳答案

我现在找不到它,但在某些时候我读到 UMS 内核端实现使用了英特尔的 LDT映射每个 UMS 线程。

8192正好是LDT表的条目数。 LDT 可以在 Win7 内核中以多种创新方式进行管理,因此 8192 可能是每个进程、每个线程或每个内核的限制。您必须尝试设置处理器关联性或拥有更多 UMS 调度程序线程,以查看是否可以超过此限制。

关于c++ - 最大用户模式调度程序线程数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27100144/

相关文章:

asp.net-mvc - ASP.NET——启动一个线程在未来几分钟内工作?

c++ - AVL 树 C++ 的 Ostream 运算符

c - C 中的 Blob 计数函数

c - 如何在其他目录下执行?

c - 从C中的文件读取空格分隔的值时出现段错误

java - 变量在静态时发生变化,在非静态时保持不变

java - 如何实时读写一个进程并在JTextArea中实时显示输出? (Java Swing )

c++ - 无法在 OpenGL 上使用不同的 VAO 渲染不同的网格

c++ - C++动态链接库中的回调函数

c++ - 使用 malloc/new 时无法编译 stm32l4r5xx