Windows中的线程ID大于0xFFFF

时间:2014-06-04 15:15:31

标签: windows winapi

我们有一个大而老的软件项目。该软件在较旧的操作系统上运行,因此它具有OS-Wrapper。今天它在Windows上运行。 在OS-Wrapper中,我们有结构来管理线程。此结构的一个成员是thread-Id,但它是使用uint16_t定义的。将使用Win-API createThreadEx生成线程ID。 由于某个月我们的客户之一出现了大于

的线程ID
numeric_limits<uint16_t>::max()

如果我们尝试将此成员更改为uint32_t,我们会遇到大麻烦。即使我们修复它,我们也必须测试修复。

所以我的问题是:如何在Windows中获得大于0xffff的线程ID?如何才能达到这个目标?

2 个答案:

答案 0 :(得分:3)

Windows线程ID是32位无符号整数,类型为DWORD。没有要求它们低于0xffff。无论思维过程如何导致你的信念都存在缺陷。

如果您想对系统进行压力测试以创建一个线程ID高于0xffff的场景,那么您只需要创建大量线程。为了使这个成为可能,在不耗尽虚拟地址空间的情况下,创建具有非常小的堆栈的线程。您也可以创建线程暂停,因为您不需要线程来执行任何操作。

当然,强制系统分配那么多线程可能仍然有点棘手。我发现,当作为32位进程运行时,我的简单测试应用程序不会轻易生成高于0xffff的线程ID,但会将其作为64位进程执行。您当然可以创建一个64位进程,它将使用低编号的线程ID,然后允许您的32位进程继续工作,因此处理编号较低的线程ID。

这是我尝试的程序:

#include <Windows.h>
#include <iostream>

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
    return 0;
}

int main()
{
    for (int i = 0; i < 10000; i++)
    {
        DWORD threadID;
        if (CreateThread(NULL, 64, ThreadProc, NULL, CREATE_SUSPENDED, &threadID) == NULL)
            return 1;
        std::cout << std::hex << threadID << std::endl;
    }
    return 0;
}

答案 1 :(得分:2)

RE

  

如果我们尝试将此成员更改为uint32_t,我们会遇到大麻烦。即使我们修复它,我们也必须测试修复。

您当前的软件使用16位对象来存储需要32位的值,这是一个错误。所以你必须修复它,并测试修复。至少有两个实用修复:

  • 更改id的声明及其所有用途。
    它可以真正帮助找到id的所有复制,引入一个不可隐式转换为整数的专用类型,例如基于C ++ 11 的枚举类型

  • 添加间接层。
    可能无需更改数据,只需更改线程库实现。

更深层次的修复可能是用C ++ 11标准库线程替换当前的线程。

无论如何,你需要做一些工作和/或一些费用。