Linux 系统调用期间的用户模式和内核模式切换

Linux 系统调用期间的用户模式和内核模式切换,linux,linux-kernel,operating-system,kernel,Linux,Linux Kernel,Operating System,Kernel,从广义上讲,在linux系统调用期间会发生以下哪种情况 用户模式进程被提升到内核模式,执行内核代码(中断服务例程),然后返回到正常模式。换句话说,是用户进程在消耗CPU 有一个内核进程总是在内核模式下运行。用户模式进程将任务(以系统调用的形式)分派到内核进程。内核进程完成作业并将结果返回给用户模式进程。换句话说,在这段时间内,用户进程是空闲的,而内核进程是消耗CPU的进程 还有别的 它主要是1,但有点像2 从usermode应用程序的角度来看,系统调用本身是同步发生的。但是,通常情况下,系统调用

从广义上讲,在linux系统调用期间会发生以下哪种情况

  • 用户模式进程被提升到内核模式,执行内核代码(中断服务例程),然后返回到正常模式。换句话说,是用户进程在消耗CPU
  • 有一个内核进程总是在内核模式下运行。用户模式进程将任务(以系统调用的形式)分派到内核进程。内核进程完成作业并将结果返回给用户模式进程。换句话说,在这段时间内,用户进程是空闲的,而内核进程是消耗CPU的进程
  • 还有别的

  • 它主要是1,但有点像2

    从usermode应用程序的角度来看,系统调用本身是同步发生的。但是,通常情况下,系统调用没有需要返回的内容,因此它会使进程处于休眠状态。这并不总是发生;一些简单的系统调用实际上是同步完成的。但是,有些需要等待长时间运行的I/O任务完成

    内核具有异步处理事物的中断处理程序和内核线程。例如,您的硬盘中断了系统,表明它最终检索到了您正在读取的文件。这些异步事件中的一个可以出现并唤醒您的进程,因为系统调用已经具备了返回到用户空间所需的功能


    因此,看起来整个过程是同步发生的,但这只是一种错觉。

    为了让处理器进入内核(或其他提升)模式,它必须通过中断或异常来实现。因为您询问的是系统调用,所以我们处理的是异常

    [由于过于简单化的风险,特别是英特尔的怪异…] 任何硬件异常(例如,访问冲突、被零除、页面错误)都会导致处理器进入内核模式。每个异常都有一个由处理器定义的数字。当异常发生时,处理器将分派给异常处理程序。通常,处理器具有定义异常处理程序数组的位置和长度的寄存器。当发生异常#2时,CPU调用数组中的第三个处理程序(0、1、2)

    处理器总是有针对特定目的(如调试和系统调用)触发异常的指令

    要进行系统调用,您需要调用处理器指令,该指令会导致异常,并将异常分派给执行系统调用的异常处理程序。在系统调用结束时,处理程序调用从异常/中断返回的特殊指令,该指令将处理器返回到用户模式

    因此,你的#1基本上是正确的

    在大多数操作系统中,您的#2是完全错误的。中断和异常由当前正在执行的进程处理(Linux使用不同的术语,但在功能上是相同的)


    如果您的进程对磁盘进行了读取,它可能会在等待响应时挂起。当中断发出磁盘I/O完成的信号时,另一个进程将运行。该进程将处理I/O的中断,然后将I/O请求排入进程队列,并将进程状态设置为runnable。下次您的进程计划运行时,它可以接收已完成的I/O请求。

    因此,这意味着内核进程/线程在为用户进程的系统调用服务时也可以执行一些代码(消耗一些CPU周期)。由于内核线程/进程与用户进程具有不同的pid,因此CPU使用将计入内核进程而不是用户进程。我实际上是在分析我的应用程序,我看到一些内核工作线程占用了一些CPU周期。我想知道我的应用程序是否导致kworker线程进行一些计算。如果我错了,请纠正我。我不是很有信心,但我想说,绝大多数时间都应该正确地考虑到你的过程。
    kworker
    线程所做的任何事情都应该被认为是系统中发生的其他事情的副作用,而不是应用程序的直接后果。但很难说,这里没有“内核进程”,只有内核内存空间,它是每个进程的一部分,所以更容易切换。如果这是一个单独的过程,你必须从头重新映射内存。