当前位置: 首页 > 面试题库 >

内核堆栈和用户空间堆栈

徐淳
2023-03-14
问题内容

内核堆栈和用户堆栈有什么区别?为什么要使用内核堆栈?如果在ISR中声明了局部变量,它将存储在哪里?每个进程都有自己的内核堆栈吗?那么,进程如何在这两个堆栈之间进行协调?


问题答案:
  1. 内核堆栈和用户堆栈有什么区别?

简而言之,除了在内存中使用不同的位置(并因此为堆栈指针寄存器使用不同的值)之外,什么也没有,而且通常使用不同的内存访问保护。也就是说,在用户模式下执行时,即使映射了内核内存(其中一部分是内核堆栈)也将不可访问。反之亦然,在没有内核代码明确要求的情况下(在Linux中,通过诸如之类的功能copy_from_user()),通常无法直接访问用户内存(包括用户堆栈)。

  1. 为什么使用[单独的]内核堆栈?

特权与安全性分离。首先,用户空间程序可以使它们的堆栈(指针)成为他们想要的任何东西,并且通常没有架构上的要求就可以拥有一个有效的堆栈。因此,内核不能
信任 用户空间堆栈指针是有效的也不可用,因此将需要一组在其自己的控制之下。不同的CPU架构以不同的方式实现此目的。当发生特权模式切换时,x86
CPU会自动切换堆栈指针,并且可以通过特权代码(即仅内核)配置用于不同特权级别的值。

  1. 如果在ISR中声明了局部变量,它将存储在哪里?

在内核堆栈上。内核(即Linux内核)不会 ISR直接挂钩到x86架构的 中断门
,而是将中断分派委托给通用的内核中断进入/退出机制,该机制可以在调用注册的处理程序之前保存中断前寄存器的状态。
。调度中断时,CPU本身可能会执行特权和/或堆栈切换,并且内核会使用/设置该切换,以便公用中断入口代码已经可以依赖存在的内核堆栈。
就是说,在执行内核代码时发生的中断将简单地(继续)在那时使用内核堆栈。如果中断处理程序具有深层嵌套的调用路径,则可能导致堆栈溢出(如果深层内核调用路径被中断,并且处理程序导致了另一条深层路径;在Linux中,文件系统/软件RAID代码被iptables处于活动状态的网络代码中断了)已知会在未调整的较旧内核中触发此类问题……解决方案是增加此类工作负载的内核堆栈大小)。

  1. 每个进程都有自己的内核堆栈吗?

不仅仅是每个进程-每个 线程
都有自己的内核堆栈(实际上,也有自己的用户堆栈)。请记住,进程和线程(对于Linux)之间的唯一区别是多个线程可以共享一个地址空间(形成一个进程)。

  1. 流程如何在这两个堆栈之间进行协调?

完全没有-
不需要。调度(如何/何时运行不同的线程,如何保存和恢复它们的状态)是操作系统的任务,而进程不必为此担心。创建线程时(每个进程必须至少有一个线程),内核会为它们创建内核堆栈,而用户空间堆栈则由用于创建线程的任何机制显式创建/提供(函数类似于makecontext()pthread_create()允许调用者指定要用于“子”线程堆栈的内存区域)或继承(通过按访问内存克隆,在创建新进程时通常称为“写时复制”
/ COW)。
那就是 (状态,其中包括线程的堆栈指针)。 这有多种方式:UNIX信号setcontext()pthread_yield()/
pthread_cancel(),… -但这disgressing从原来的问题有点。



 类似资料:
  • 问题内容: Java内存空间(Perm空间,Space Stack,堆空间)之间有什么区别? JVM什么时候使用一个或另一个? 如果我使用Scala / Groovy / etc等,会有区别吗? 问题答案: 只是 堆空间:所有活动对象都分配在这里。 堆栈空间:在方法调用或变量实例化中存储对对象的引用以获取变量。 烫发空间:存储已加载的类信息 例如: 执行完上述行之后,内存状态将是这样。 堆:存储“

  • 问题内容: 是局部变量,将其存储在堆或堆栈中的何处? 问题答案: 在堆上。每当您用来创建对象时,它都会在堆上分配。

  • 问题内容: 在Java多线程中,术语和之间在语义上有区别吗? 问题答案: 每个线程都有自己的调用堆栈,“调用堆栈”和“线程堆栈”是同一件事。将其称为“线程堆栈”只是强调了调用堆栈特定于线程。 Bill Venners将此称为Java堆栈: 启动新线程时,Java虚拟机将为该线程创建一个新的Java堆栈。如前所述,Java堆栈将线程的状态存储在离散的帧中。Java虚拟机仅直接在Java堆栈上执行两项

  • 本文向大家介绍Java中的堆栈和堆内存之间的区别,包括了Java中的堆栈和堆内存之间的区别的使用技巧和注意事项,需要的朋友参考一下 JVM将内存空间分为两部分,一个是堆栈,另一个是堆空间。堆栈空间主要用于存储方法执行的顺序和局部变量。 堆栈始终按照LIFO顺序存储块,而堆内存使用动态分配来分配和取消分配内存块。  分配给堆的内存将一直存在,直到发生以下事件之一: 程序终止  无记忆  相反,分配给

  • 我试图了解分配给堆栈和堆的内存量。假设sizeof(char)=1字节,sizeof(void*)=4字节。给定以下代码: 我们被告知分配给堆的内存量是5个字节,我明白这确实是malloc(strlen(str2)=5)中的量。但是,我不明白的是分配给堆栈的内存量是如何达到18个字节的?我想如果他们给我们一个指针大小是4个字节的信息,那么我们有4个字节的指针str1和另外6个字节的数组str2(包

  • 问题内容: 这是声明Java数组的常用方法: 但是此数组正在使用堆空间。有没有一种方法可以使用像c ++这样的堆栈空间来声明数组? 问题答案: 一言以蔽之。 存储在堆栈中的唯一变量是基元和对象引用。在您的示例中,引用存储在堆栈上,但它引用堆上的数据。 如果由于要确保清理内存而问来自C ++的问题,请阅读有关垃圾回收的信息。简而言之,Java自动处理清理堆中的内存以及堆栈中的内存。