• [转]进程的用户栈和内核栈


    原文: https://blog.csdn.net/wwh578867817/article/details/49076659

    每一个进程都包含用户栈和内核栈,用户栈和内核栈分别分配在用户地址空间和内核地址空间。

    进程是程序的一次执行过程。用剧本和演出来类比,程序相当于剧本,而进程则相当于剧本的一次演出,舞台、灯光则相当于进程的运行环境。

    进程的堆栈

    每个进程都有自己的堆栈,内核在创建一个新的进程时,在创建进程控制块task_struct的同时,也为进程创建自己堆栈。一个进程 有2个堆栈,用户堆栈和系统堆栈;用户堆栈的空间指向用户地址空间,内核堆栈的空间指向内核地址空间。当进程在用户态运行时,CPU堆栈指针寄存器指向的 用户堆栈地址,使用用户堆栈,当进程运行在内核态时,CPU堆栈指针寄存器指向的是内核栈空间地址,使用的是内核栈;

    进程用户栈和内核栈之间的切换

    当进程由于中断或系统调用从用户态转换到内核态时,进程所使用的栈也要从用户栈切换到内核栈。系统调用实质就是通过指令产生中断,称为软中断。进程因为中断(软中断或硬件产生中断),使得CPU切换到特权工作模式,此时进程陷入内核态,进程进入内核态后,首先把用户态的堆栈地址保存在内核堆栈中,然后设置堆栈指针寄存器的地址为内核栈地址,这样就完成了用户栈向内核栈的切换。

    当进程从内核态切换到用户态时,最后把保存在内核栈中的用户栈地址恢复到CPU栈指针寄存器即可,这样就完成了内核栈向用户栈的切换。

    这里要理解一下内核堆栈。前面我们讲到,进程从用户态进入内核态时,需要在内核栈中保存用户栈的地址。那么进入内核态时,从哪里获得内核栈的栈指针呢?

    要解决这个问题,先要理解从用户态刚切换到内核态以后,进程的内核栈总是空的。这点很好理解,当进程在用户空间运行时,使用的是用户 栈;当进程在内核态运行时,内核栈中保存进程在内核态运行的相关信息,但是当进程完成了内核态的运行,重新回到用户态时,此时内核栈中保存的信息全部恢 复,也就是说,进程在内核态中的代码执行完成回到用户态时,内核栈是空的。

    理解了从用户态刚切换到内核态以后,进程的内核栈总是空的,那刚才这个问题就很好理解了,因为内核栈是空的,那当进程从用户态切换到内核态后,把内核栈的栈顶地址设置给CPU的栈指针寄存器就可以了。

  • 相关阅读:
    1221D
    1249E
    D. Yet Another Monster Killing Problem
    大佬传送门
    Zookeeper客户端连接报错
    搭建PXC集群
    Docker分布式环境
    Docker使用
    Docker入门
    MySQL数据库集群概述
  • 原文地址:https://www.cnblogs.com/caiyao/p/10414927.html
Copyright © 2020-2023  润新知