linux系统中,进程进行系统调用进入内核态时,是该进程本身进入内核态还是操作系统新开了一个内核线程?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux系统中,进程进行系统调用进入内核态时,是该进程本身进入内核态还是操作系统新开了一个内核线程?相关的知识,希望对你有一定的参考价值。

一直不太明白,进程进入内核态时的过程是,进程本身有一个状态标志位,将这个状态标志位由用户态改为内核态,系统调用完成后再切换回用户态;还是操作系统将这个用户态进程阻塞,重新开一个系统线程完成相关的系统调用任务后,再唤醒该用户态进程?

可以说是进程本身进入内核态。
系统调用调用了内核代码,但是,还是属于这个进程的进程上下文。
进程的切换要依靠时钟中断。
还要明白内核线程的功能,与进程切换没关系。追问

那我假设目前有一个进程进行系统调用进入了内核态,那此时由于时钟中断,运行进行schedule进行调度,那此时进行调度时,系统的运行队列(runqueue)中该进程被一个内核线程代替了么?
换句话说,这个时候该进程的task_struct是否还存在于runqueue中?
如果存在,那此时该进程的task_struct和该进程处于用户态时有什么区别么?

追答

schedule的调用不只是发生在时钟中断之后。

linux内核在2.6以后支持内核抢占,内核抢占可能发生在几种情况下面:

    进程上下文的内核代码阻塞

    内核代码显示的调用schedle,这时候它明白自己是抢占安全的

    中断代码返回

    抢占嵌套

发生了内核抢占后,schedule程序重新选择一个程序执行,这个程序可能是原来被抢占的程序,也可能不是,不能说是一个内核线程,内核线程的是内核创建的一些专门线程,它与用户进程一样参与调度。

进程是否处在可执行队列中,要看进程被抢占时的状态,如果是因为进程阻塞,肯定是不在可执行队列中的,如果是被中断抢占的,那么可能处在可执行队列中。

进程是否处于可执行队列,由当前的进程运行状态决定,如果是TASK_RUNNING,就是处于。

追问

你没有回答我的问题,我没有说schedule一定发生在时钟中断之后。
我的问题是,如果一个进程进行系统调用进入内核态以后(假设其没有被阻塞),此时如果发生schedule(不管是什么原因吧),那在运行schedule时,runqueue中是否存在该进程的task_struct,如果存在,通过task_struct如何判断一个进程是处于内核态还是用户态?(或者无法判断?)

追答

刚才已经回答了啊,每个cpu核的runqueue不就是其可执行队列?被抢占后是否还在可执行队列取决于被抢占前的状态,在内核态被抢占的的话,该进程恢复执行还是内核态。

参考技术A 系统调用实际上是应用程序在用户空间激起了一次软中断,在软中断之前要按照规范,将各个需要传递的参数填入到相应的寄存器中。软中断会激起内核的异常处理,此时就会强制陷入内核态(此时cpu运行权限提升),软中断的异常处理函数会根据应用软件的请求来决定api调用是否合法,如果合法选择需要执行的函数,执行完毕后软中断会填入返回值,安全地降低cpu权限,将控制权交还给用户空间。所以内核提供的api调用,你完全可以认为就是一个软件包,只不过这些软件包你不能控制,只能请求内核帮你执行。
因为内核态和用户态属于同一个进程,所以不存在同一进程内内核态阻塞用户态这种说法,只能是进程是否在内核态执行了阻塞操作而被阻塞。追问

按这个说法,是task_struct中有个标志表示该进程目前处于用户态或者是内核态么?

追答

这个不敢确定,没看过那部分代码。

参考技术B 只能说不可能是后者。追问

为什么 不可能 ?

追答

线程的目的是同时处理多件事情,
用户态到内核态具体的切换操作
[1] 从当前进程的描述符中提取其内核栈的ss0及esp0信息。
[2] 使用ss0和esp0指向的内核栈将当前进程的cs,eip,eflags,ss,esp信息保存起来,这个
过程也完成了由用户栈到内核栈的切换过程,同时保存了被暂停执行的程序的下一
条指令。
[3] 将先前由中断向量检索得到的中断处理程序的cs,eip信息装入相应的寄存器,开始
执行中断处理程序,这时就转到了内核态的程序执行了。

Linux内核与内核函数与操作系统,系统调用,这几者的联系是什么?

实现内核各种功能的就是内核函数,而操作系统是有:uboot、内核、文件系统和应用程序组成的。系统调用是操作系统提供给用户层或者说是应用层的一个接口,因为应用层是不能直接访问内核的(内核态)。 参考技术A 一般情况下,系统内核都是位于hardware层的直接上层,也就是说kernel实现了硬件抽象,直接控制硬件。
系统函数指操作系统提供的API,主要区别于具体语言实现库函数。
系统调用就是调用系统函数。
参考技术B 可以说是进程本身进入内核态。
系统调用调用了内核代码,但是,还是属于这个进程的进程上下文。
进程的切换要依靠时钟中断。
还要明白内核线程的功能,与进程切换没关系。

以上是关于linux系统中,进程进行系统调用进入内核态时,是该进程本身进入内核态还是操作系统新开了一个内核线程?的主要内容,如果未能解决你的问题,请参考以下文章

2017-2018-1 20179202《Linux内核原理与分析》第九周作业

linux进程为啥有用户栈和内核栈,

进程上下文

2017-2018-1 20179209《Linux内核原理与分析》第九周作业

2017-2018-1 20179219《Linux内核原理与分析》第九周作业

结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程