在多线程程序中,每个线程都拥有一块独立的栈,这块栈是其他线程无法访问的私有资源。
因此,存储在该栈中的局部变量无需考虑线程同步问题。但若该局部变量涉及 RAII,则需要额外注意。
线程与进程共享大部分资源,仅有少量独立资源(如程序计数器、寄存器组和栈)。值得注意的是,DLL 的堆栈是独立的,因此在 DLL 中创建的线程情况可能有所不同。
void worker()
{
// char a[4096000];
char a[1024*924];
while (true)
Sleep(5000);
}
int main()
{
for (int i = 0; i < 100; i++)
{
// worker();
std::thread t(worker);
t.detach();
cout << "thread ok " << i << endl;
}
while (true)
{
Sleep(1000);
}
system("pause");
return 0;
}
从多线程的使用场景来看,各线程的栈理应相互独立。VS 设置页中的"堆栈保留大小"指的是每个线程栈的最大增长上限,默认为 1M。上面的代码不会导致栈溢出——正因为每个线程最多占用 1M,启动 100 个线程后,任务管理器中的内存占用大约为 90+ MB。
每个线程退出后,其对应的栈即被释放。
函数调用栈的释放机制也是如此:
线程的栈会在函数 return 之后释放。若是被其他线程强制终止,则栈不会被释放,从而导致内存泄漏。
A stack is freed when its thread exits. It is not freed if the thread is terminated by another thread.
关于线程栈大小的 MSDN 说明:
https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms686774.aspx