多线程中栈和调用栈的区别是什么?

6

在阅读有关线程共享的所有内容时,我遇到了“调用堆栈”这个术语。虽然我知道线程有自己的堆栈,它们不与其他线程共享,但我不明白在线程方面调用堆栈是什么意思。我看过一些答案,但它们并不是很清楚。请解释一下调用堆栈的含义以及在多任务环境中如何与堆栈不同。谢谢。


1
阅读调用栈。在线程上下文中,它也完全相同。 - P.P
"调用栈"指的是仅限于"栈"的堆栈。"栈"是表示的缩写形式。 - Karthik Balaguru
3个回答

3
请解释一下调用栈的含义,并说明在多任务环境下它与堆栈的区别。
虽然这两个术语的区别很微妙,但我理解是这样的。通常人们会将它们混为一谈,但调用栈仅是一个数据结构。它描述了一系列函数调用以及相关状态,例如本地变量的值、返回状态等等,形成了一个栈。
堆栈也是一种数据结构,但它最终是一个内存分配器。它汇集了为线程分配的内存,用于诸如调用栈之类的内容,具有非常简单、恒定时间、对称的推入和弹出风格的内存分配和释放。
可以粗略地将其视为std :: vector和std :: allocator之间的关系。 std :: vector严格是一个数据结构。 std :: allocator为其分配内存(通常涉及一个数据结构,但仅用于内存管理)。但std :: vector不一定必须使用std :: allocator。
从概念上讲,调用栈实际上并不一定要使用堆栈来分配内存。实践中很难找到一个编译器会这样做。例如,调用栈实际上可以使用堆代替堆栈。每次只需推送函数调用的参数时,它实际上需要进行线性时间内存分配。这很糟糕,但它与调用栈的概念并不冲突。
通常,调用栈使用本地线程堆栈来分配内存,因为这是实用的、高效的,符合预期的后进先出的分配/释放特性,并允许每个线程拥有自己的内存空间(缓解了与共享内存访问相关的瓶颈)。

2
一个调用栈是一种堆栈数据结构,它存储有关计算机程序活动子例程的信息。
线程堆栈是线程的私有堆栈,您已经了解它。
如果线程正在执行函数,则当前函数的调用栈将存储到线程堆栈中。
这两个东西本质上是相同的。它们都是堆栈数据结构。

0

阅读关于 调用栈多线程 的维基页面。

在纯理论中,C 的实现甚至可能不使用任何堆栈。在实践中,我听说过的每个编译好的 C 实现都使用一个调用堆栈,它是处理器堆栈(某些处理器,可能 Itanium IA-64,有两个机器堆栈)当有一个时(据我所知,IBM z Series 主机没有任何 硬件 堆栈,这是一些寄存器的常规使用)。因此,对于大多数处理器和ABI (ARM、x86、x86-64 等),调用堆栈就是堆栈,每个线程都有自己的堆栈。


1
实际上,IBM大型机有一个很棒的硬件栈,通常称为“链接栈”(Linkage Stack)。程序员可以选择管理自己的栈(可能更快),或使用硬件提供的栈(更健壮和安全)...这在很大程度上取决于开发者的个人喜好。 - Valerie R
1
另外一个要点是编译器倾向于通过精心控制调用栈的管理来优化函数调用开销。例如,编译器可能会安排对简单函数的调用,以便函数可以自由地使用某些硬件寄存器进行工作,避免在函数调用之间保存和恢复这些寄存器的需要。聪明地处理这些事情可能会给您带来20-30%的CPU时间提升,无论架构如何,但这意味着调用堆栈对于每个函数可能都不同,具体取决于优化器的操作。 - Valerie R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接