C++ CreateThread会干扰VirtualAlloc的使用吗?

C++ CreateThread会干扰VirtualAlloc的使用吗?,c++,winapi,virtual-memory,C++,Winapi,Virtual Memory,CreateThread分配的堆栈空间是否可能干扰VirtualAlloc的使用?我找不到任何讨论或文档来精确解释允许在哪里分配堆栈空间 以下更准确地说明了我的问题: uint8_t *baseA = (uint8_t*)VirtualAlloc(NULL,1,MEM_RESERVE,PAGE_NOACCESS); // Create a thread with the default stack size HANDLE hThread = CreateThread(NULL,0,SomeTh

CreateThread
分配的堆栈空间是否可能干扰
VirtualAlloc
的使用?我找不到任何讨论或文档来精确解释允许在哪里分配堆栈空间

以下更准确地说明了我的问题:

uint8_t *baseA = (uint8_t*)VirtualAlloc(NULL,1,MEM_RESERVE,PAGE_NOACCESS);

// Create a thread with the default stack size
HANDLE hThread = CreateThread(NULL,0,SomeThreadProc,NULL,NULL,NULL);

// Possibly create even more threads here.

// Can this ever fail in the absence of other allocators? It doesn't here...
uint8_t *baseB = (uint8_t*)VirtualAlloc(NULL,1,MEM_RESERVE,PAGE_NOACCESS);

// Furthermore, in this test, baseB-baseA == 65536 (unless the debugger did something),
// so nothing appeared between baseA and baseB... not even enough space for the
// full 64kb of wastage, as baseA points to 4096 bytes by itself

如果它确实使用了一些类似的
VirtualAlloc
,有没有办法改变Windows在给定进程中分配堆栈空间的方式?

Windows NT内核以高中断优先级处理内存alloc操作,也以线程安全的方式

这意味着一个进程中只有一个线程可以同时分配内存,这使得所有分配进程(理论上)都是线程安全的。 堆栈分配和虚拟分配之间不应该有任何干扰

你也应该记住,你可以分配1GB的空间,但你的程序仍然只使用2mb的RAM

这是因为windows“预先分配”了虚拟空间,但在您使用虚拟空间(在虚拟空间上写入)之前,它不会分配虚拟空间

实际上,内存管理要复杂得多,但现在你可以向舒尔保证,任何分配操作都不应受到干扰,因为windows会将进程锁定在一个内核上,延迟所有其他线程的alloc请求,只要分配得到处理。(僵局)


*编辑:这也意味着分配和取消分配是一个需要性能的过程,如果你分配数百万个小比特。由于这种死锁行为,分配/取消分配更大的内存区域总是更好。

windows NT内核以高中断优先级处理内存分配操作,也是以线程安全的方式

这意味着一个进程中只有一个线程可以同时分配内存,这使得所有分配进程(理论上)都是线程安全的。 堆栈分配和虚拟分配之间不应该有任何干扰

你也应该记住,你可以分配1GB的空间,但你的程序仍然只使用2mb的RAM

这是因为windows“预先分配”了虚拟空间,但在您使用虚拟空间(在虚拟空间上写入)之前,它不会分配虚拟空间

实际上,内存管理要复杂得多,但现在你可以向舒尔保证,任何分配操作都不应受到干扰,因为windows会将进程锁定在一个内核上,延迟所有其他线程的alloc请求,只要分配得到处理。(僵局)


*编辑:这也意味着分配和取消分配是一个需要性能的过程,如果你分配数百万个小比特。由于这种死锁行为,最好分配/取消分配较大的内存区域。

堆栈空间可以分配到进程地址空间的任何位置。目前没有关于这方面的文件,将来也不太可能出现此类文件

您可以安全地假设线程和虚拟alloc的创建是独立的。如果不是这样,很多东西都会被破坏。分配器不能给出重叠的地址范围。这是不可想象的。问题出在别的地方

唯一看起来像相关性的东西是使用的内存量和虚拟地址空间碎片。在这种情况下,最新的请求将完全失败

我在一个内存分析实用程序上工作

此图显示了每个分配大小的虚拟分配数的分布

这是32位进程的地址空间内容示例(蓝色-提交,洋红色-保留,绿色是空闲内存)


我在这里写的是基于实际经验。

堆栈空间可以分配到进程地址空间的任何位置。目前没有关于这方面的文件,将来也不太可能出现此类文件

您可以安全地假设线程和虚拟alloc的创建是独立的。如果不是这样,很多东西都会被破坏。分配器不能给出重叠的地址范围。这是不可想象的。问题出在别的地方

唯一看起来像相关性的东西是使用的内存量和虚拟地址空间碎片。在这种情况下,最新的请求将完全失败

我在一个内存分析实用程序上工作

此图显示了每个分配大小的虚拟分配数的分布

这是32位进程的地址空间内容示例(蓝色-提交,洋红色-保留,绿色是空闲内存)


我在这里写的是基于一个真实的经验。

+1对于“这是不可想象的”-操作系统在启动时会很快崩溃,甚至可能没有时间进行BSOD。谢谢你的回答。也许“干涉”是这个问题的一个严厉的词。我要问的是,基本上,如果
CreateThread
,可以在任何地方分配堆栈空间——您回答了这个问题。通过“interfere”,我问它是否可以分割进程的虚拟地址空间(但是,现在我想起来了,它还能在哪里分配它呢?)。因此,随机线程分配似乎会导致任何自定义分配器都无法解决的碎片问题。这是所有
VirtualAlloc
分配的大小总和与地址空间本身大小的比率。我在Windows上使用32位进程的经验表明,当该值小于85-90%时,一切都或多或少正常。当超过90%时,各种问题开始出现。+1表示“这是不可想象的”-操作系统在启动时会很快崩溃,甚至可能没有时间进行BSOD。谢谢您的回答。也许“干涉”是这个问题的一个严厉的词。基本上,我所要求的是,如果
CreateThread
,可以在任何时候分配堆栈空间