linux - 调度 - 每个进程使用一个或多个内核堆栈进行上下文切换

标签 linux linux-kernel kernel scheduled-tasks context-switch

考虑到 Linux 的情况,我们为每个用户堆栈都有一个内核堆栈,据我所知,每当发生上下文切换时,我们都会切换到当前进程的内核模式。

这里我们保存当前进程的当前状态,寄存器,程序数据等,然后调度器(不确定是否运行在这个内核中)保存PCB并加载下一个要调度的进程的PCB。

现在第一个问题是上面的解释是否对你有意义,考虑上下文切换,其中每个进程也有一个“专用”内核堆栈。

我的问题的另一部分是,如果所有进程都有一个内核堆栈,上下文切换将如何发生?

最佳答案

每个进程都有自己的内核堆栈。

我将以最新的内核为例。

include/linux/sched.h中,有一个名为thread_union的联合体。其定义如下:

union thread_union {
#ifndef CONFIG_THREAD_INFO_IN_TASK
    struct thread_info thread_info;
#endif
    unsigned long stack[THREAD_SIZE/sizeof(long)];
};

当一个新进程被创建时,内核会分配一个thread_union给它,每个进程都会有它“专用的”thread_union

  1. 第一个成员 thread_info 是一个结构,它包含指向此进程的 task_struct 的指针。
  2. 第二个成员stack是本进程的内核栈。
  3. 这是一个联合体,所以两个成员使用相同的内存空间。 thread_info 不是很大,所以内核堆栈有足够的空间。

当进程调用系统调用时,它会使用自己的内核栈,并将指向用户栈的%ESP保存在内核栈中。

每个进程都有自己的thread_union,因此它们有自己的“专用”内核堆栈。

关于linux - 调度 - 每个进程使用一个或多个内核堆栈进行上下文切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45699190/

相关文章:

linux - ELF 的代码段何时加载到内存中?

linux - mmap 总线错误

c++ - 将空数据写入非阻塞套接字会导致 epoll_wait 挂起

linux-kernel - MAP_HUGETLB 是一致内存的同义词吗? (成功时)

c - 什么触发了 0x08 中断?

linux - Endianness:用户空间中的le32_to_cpu

c++ - Qt 4.8.6/Linux Mint 中没有西里尔字母

c++ - 当守护线程在后台工作时返回一个函数 (c++)

c - 如何优雅地禁用中断线而不导致内核崩溃?

编译动态链接内核