我们有一个大而老的软件项目。该软件在较旧的操作系统上运行,因此它具有OS-Wrapper。今天它在Windows上运行。 在OS-Wrapper中,我们有结构来管理线程。此结构的一个成员是thread-Id,但它是使用uint16_t定义的。将使用Win-API createThreadEx生成线程ID。 由于某个月我们的客户之一出现了大于
的线程IDnumeric_limits<uint16_t>::max()
如果我们尝试将此成员更改为uint32_t,我们会遇到大麻烦。即使我们修复它,我们也必须测试修复。
所以我的问题是:如何在Windows中获得大于0xffff的线程ID?如何才能达到这个目标?
答案 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标准库线程替换当前的线程。
无论如何,你需要做一些工作和/或一些费用。