进程切换过程详解

/*

注:在学习内核的时候有一个困难,那就是任何一个模块都不是孤立的,比如进程的调度就设计到中断处理、信号处理还有进程上下文的切换等等。作为一个初学者,想一下子把操作系统的整个运行过程都清晰地展现在脑海是不现实的。尽管如此,每个模块还是有它所关注的焦点,我们所采取的策略是把整个操作系统分为几个大模块,比如:进程的管理、内存管理、文件系统等等。然后把这些大模块进一步分解成一个个小模块,比如进程的管理可以细分为进程的创建、进程的切换、系统调用的处理、信号的处理等等。在分析每一个模块时,先把其他的模块抽象化,千万不要陷入其他模块的细节当中,,也可以说这是一种各个击破的方法,当你把每个小模块的功能搞清楚后,到最后整个操作系统的运行过程就很清晰了!

*/

在上一篇博客中,我们提到当一个任务从系统调用处理函数返回之前会检查是否需要进行进程切换。那么什么时候会发生进程的切换呢(任务调度)?当系统发生硬件中断、系统调用或者时钟中断时,就有可能发生进程的切换。 下面我们以时钟中断为例来看看进程的切换是如何进行的。

在此之前,我们先要做一个说明,由于我们并没有开始介绍进程的详细知识,对进程的详细介绍将放在进程的创建这一篇博客中(还没开始写O(∩_∩)O~),因此在这里我们先对进程做一个粗略的抽象:一个任务(就是进程)含有代码段、数据段、堆栈段,还有一个任务状态段TSS。这个任务状态段TSS记录当前任务的所有状态信息,包括寄存器、系统参数等等。TSS段的描述符放在TR寄存器中(也就是说访问TR就能访问当前任务的TSS段了)。

假设此刻CPU正在执行进程1,我们知道:系统有一个时钟频率,每隔一段时间就会发生一次时钟中断,这个时间段我们称为一个滴答。假设经过了一个滴答,系统发生时钟中断,此时时钟中断处理程序就会被自动调用(timer_interrupt),timer_interrupt定义在kernel/System_call.s中,如下图所示:

同我们上一篇讲的_system_call一样,它首先会执行一些保护现场的工作,接着在第189行代码中把_jiffies的值加1(_jiffies表示自系统启动以来经过的滴答数),接下来第192-194的代码将执行此次时钟中断的特权级CPL压入堆栈,用来作为后面do_timer的参数,接下来开始执行do_timer,do_timer函数定义在Kernel/Sched.c中,这个函数的主要作用是将当前进程的用户态执行时间或内核态执行时间加1,然后将当前进程的剩余时间片减1.

如果当前进程的时间片还有剩余,那么直接return返回继续执行,接下来判断当前任务的CPL是否是0,如果是0,说明当前任务是在内核态被中断的,而Linux0.11中内核态是不能被抢占的,所以直接返回执行,如果不是0,则执行进程调度程序schedule()。接下来我们来分析schedule()这个函数,schedule函数同样定义在Sched.c中,它里面包含下面两段代码:

这段代码的作用是:遍历任务数组,检查它们的报警定时值,如果该值小于jiffies,说明该任务的alarm时间已经过了,那么就在它的信号位图中置SIGALRM信号,表示向任务发送SIGALARM信号,然后将alarm清零,接下来检查是不是还有别的未被阻塞的信号,如果有并且当前的进程状态是可以被打断的,那么把这个任务置为就绪态。

第124-142行的代码重新遍历整个任务数组,找出任务状态处于TASK_RUNING并且时间片最长的那个任务。并调用swith_to()函数切换到那个任务。swith_to函数定义在include/Linux/Sched.h中。

switch_to是一段汇编代码,下面来解释一下这段代码的含义:首先检查要切换的任务是不是当前任务,如果是则直接退出。接下来把任务n(要切换去的任务)的TSS段放到_tmp.b中,然后把任务n放入_current中,把当前任务放入%ecx中切换出来,然后执行一个长跳转到*&_tmp的位置(这是新任务的TSS地址处),此时CPU会把所有寄存器的内容保存到当前任务TR执行的TSS段中,然后把新任务的TSS段中的寄存器信息恢复到CPU的各个寄存器中,这样系统就正式开始执行新的任务了。第178-180的代码是判断原任务是否使用过协处理器,如果没有则直接结束。

时间: 2024-08-13 15:29:56

进程切换过程详解的相关文章

Android Phone进程启动过程详解

之前解决一个开机搜网慢的问题时,发现由于Phone进程起来以后才会主动连接RILD,因而在一定程度上Phone进程启动的时间会影响网络状态注册的快慢.适当的将Phone进程提前,可以将网络注册时间提前一点,让状态栏中信号显示的时间提前.那么,Android中作为系统的核心进程之一,Phone进程是如何启动的了? RIL运行机制请参考: http://blog.csdn.net/jason_wzn/article/details/53232022 Telephony最开始创建的是PhoneFact

Linux进程创建过程详解

本文首先使用了接口pthread_create创建一个线程,并用strace命令追踪了接口pthread_create创建线程的步骤以及涉及到的系统调用,然后讨论了Linux中线程与进程关系,最后概述了为了实现POSIX线程,Linux内核所做的修改. 一.使用pthread_create创建线程 在Linux下可以使用pthread_create来创建线程,该接口声明如下: #include <pthread.h> int pthread_create(phtread_t *thread,

可以自动切换的tab选项卡实现过程详解

可以自动切换的tab选项卡实现过程详解:关于选项卡大家一定不会陌生,应用非常的频繁,通常选项卡都是需要点击或者划过才能够实现切换.本章节分享一个能够实现自动切换的选项卡功能,并给出它的具体实现过程.代码实例如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.so

Linux网络编程——进程池实现过程详解(1)

目录 进程池 父进程的实现流程 子进程的实现流程 进程池 父进程的实现流程 1.定义数据结构pChild,申请子进程数目的结构体空间 2.通过循环,socketpair创建全双工管道,创建子进程,将子进程pid,管道对端,是否忙碌等信息存储 3.socket,bind,listen,对应的端口处于监听状态 netstat 4.epoll_create创建epfd,监控socketFd和所有子进程的管道对端 5.while(1)循环 epoll_wait等待客户端的请求及子进程是否有通知 如果so

使用HeartBeat实现高可用HA的配置过程详解

使用HeartBeat实现高可用HA的配置过程详解 一.写在前面 HA即(high available)高可用,又被叫做双机热备,用于关键性业务.简单理解就是,有2台机器 A 和 B,正常是 A 提供服务,B 待命闲置,当 A 宕机或服务宕掉,会切换至B机器继续提供服务.常见的实现高可用的开源软件有 heartbeat 和 keepalived. 这样,一台 web 服务器一天24小时提供web服务,难免会存在 web 服务挂掉或服务器宕机宕机的情况,那么用户就访问不了服务了,这当然不是我们期望

Linux系统启动过程详解

 Linux系统启动过程详解 启动第一步--加载BIOS当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬盘信息.内存信息.时钟信息.PnP特性等等.在此之后,计算机心里就有谱了,知道应该去读取哪个硬件设备了. 启动第二步--读取MBR众所周知,硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,它的大小是512字节,别看地方不大,

LAMP架构搭建以及基于LAMP架构的主流论坛和博客搭建过程详解

了解网站架构的朋友都知道,现在很多网站的架构都是采用LAMP(Linux+Apache+Mysql/Mariadb+Php)的,至于LAMP架构本身我们就不做过于深入的探讨了,今天我给大家分享的是关于如何搭建LAMP构架,以及如何基于lamp架构去搭建目前国内比较流行的两大开源论坛(phpwind.discuz)一大开源博客(wordpress),通过这个过程也就能让大家明白我们经常上的论坛以及博客,包括包括我们访问的各个网站到底是如何工作起来的. 注意:为了方便给大家展示实验效果,我们就直接关

Hadoop MapReduce执行过程详解(带hadoop例子)

https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 MapReduce运行的时候,会通过Mapper运行的任务读取HDFS中的数据文件,然后调用自己的方法,处理数据,最后输出.Reducer任务会接收Mapper任务输出的数据,作为自己的输入数据,调用自己的方法,最后输出到HDFS的文件中.整个流程如图: Mapper任务的执行过程详解 每个Mapper任

Android的学习之路(三)项目的启动过程和安装过程详解

应用的安装和启动过程: 安装:第一步:java的编译器会把这个.java文件编译成.class文件 第二部:Android的SDK提供了一个dx工具,这个工具把.class文件转义成.dex文件 第三部:打包操作,把.dex文件和资源文件进行打包,打包成一个压缩文件,然后进行签名.最后就打包成为了.apk文件 第四部:调用adb指令:adb install c:/x.apk安装到模拟器 具体过程:.JAVA---->.class--.dx-->.dex--->打包签名--->.ap