`
talin2010
  • 浏览: 524007 次
  • 性别: Icon_minigender_1
  • 来自: 河北
社区版块
存档分类
最新评论

[Linux内核完全剖析]第五章Linux内核体系结构5.7总结 进程控制

阅读更多

PCB(Process Control Block 进程控制块)又称任务数据结构,位于include/linux/sched.h中:


进程运行状态(task_struct中的state字段)
0:运行状态,当进程占用CPU时间或者已经就绪随时可由调度程序执行时(就绪态),均属于该状态。进程可以在用户态运行,也可以在内核态运行。在内核态执行的时候如果需要等待系统某个资源,则会切换到睡眠状态,也只有这种情况下内核才会进行进程切换操作。(但是在Linux2.4内核以后有了内核态的优先级相关的进程切换功能)为了避免进程切换造成的内核数据错误,内核在执行临界区代码时会禁止中断。
1:可中断的睡眠状态,进程处于该状态时,不占用CPU时间。当系统产生了一个中断或者释放了进程正在等待的资源,或者进程收到一个信号,可以唤醒从而转到就绪态。
2:不可中断的睡眠状态,除不会因为收到信号而唤醒外,其余行为均与可中断的睡眠状态类似。只有使用wake_up()函数明确唤醒时才会转到就绪态,通常是在进程需要不受干扰的等待某个事件的发生时使用。
3:暂停状态,当进程收到SIGSTOP、SIGTSTP、SIGTTIN、SIGTTOU时会进入该状态,调试期间的进程收到任何信号均会进入暂停状态,可使用SIGCONT信号使暂停的进程进入就绪态。Linux0.11中并未实现该状态,会当作进程终止来处理。
4:僵死状态,进程已经结束运行,但是父进程还没有通过wait()问询其状态,这种情况被称为僵死状态,当父进程通过wait()获取了子进程信息之后,就会彻底清除该进程在PCB中的全部信息。

进程初始化
进程0初始化的过程是系统初始化过程的一部分。
1、引导程序先把内核从磁盘加载到内存中,并开启保护模式。
2、执行系统初始化代码init/main.c。这段代码会确定物理内存的分配和使用方式。
3、分别使用初始化函数对内存管理、中断处理、设备管理、进程管理以及软硬盘硬件进行初始化。
4、系统自主切换到进程0中。
5、进程0 fork()出init进程
6、init进程进行应用环境初始化
7、执行shell登录程序
进程0在系统空闲时会被调度出来,但它会执行一个pause()使自己放弃CPU时间,然后调度程序又会去调度别的进程来执行。
上述第4步由move_to_user_mode宏来完成,它构造好栈信息,使用iret指令从内核态跳转到用户态执行。在此之前调度程序初始化函数sched_init()会对进程0的task_struct,在GDT中设置好所需TSS和LDT,并加载到tr和ldtr中。
当切换到进程0后,由于特权级发生变化,使得DS、ES、FS、GS变得无效,需要重新加载。而SS仍然是切换前的值,也就是说进程0的用户态栈是之前内核使用的栈,而内核态的栈则是在上一步被设置成了其task_struct所在页面的顶端(PAGE_SIZE+(long)&init_task)。由于创建新进程1时,需要复制进程0的task_struct,所以要保持栈的清洁。

创建新进程
fork()调用过程
1、在进程数组中找到一个还未被使用的空项,如果满了(64个进程在运行)则返回出错。
2、在主内存区申请一页来存放task_struct信息。复制当前进程的task_struct到新进程,并把新进程的state更改为不可中断的睡眠状态(防止调度进程在未新进程未初始化完成时调度它)。
3、更改新进程task_struct其他数据项。把当前进程设置为新进程的父进程,清除信号位图并复位进程统计数据,设置初始运行时间片位15。设置tss中各寄存器值,tss.eax=0(fork()后新进程的返回值),tss.esp0为新进程tss_struct所在页面的顶端,tss.ss0设置为内核数据段选择符。还有tss.ldt,以及如果使用协处理器,则许把协处理器状态保存到tss.i387。
4、设置新进程数据和代码段描述符,并复制当前进程的页表。注意,系统此时不为新进程分配实际的物理内存页面,而是共享父进程的。只有当父子进程中任一个写内存时,系统才为执行写操作的进程实际分配,这是写时复制技术(copy on write)。
5、父进程打开的文件的打开次数+1。
6、设置GDT中新任务的TSS和LDT描述符。
7、设置新任务状态位就绪态,并返回新进程号。

进程调度
Linux是优先级相关的抢占式任务调度,Linux2.4版本以后增加了内核态抢占的功能。Linux0.11采用优先级排队的调度策略:
调度函数schedule() 运行时,会先比较每个就绪的进程的counter值,选取最大的来运行。如果没有就绪进程,重新计算每个进程的counter=counter/2+priority。然后再重新扫描是否有就绪进程,如果有则运行,没有则调用进程0,进程0会调用pause()自睡眠导致schedule()函数再次调用。
schedule()函数内部会调用switch_to()宏进行进程切换,遵循以下步骤:
1、判断要切换的进程是否为当前进程,如果是则直接运行,否则进入第2 步。
2、把全局变量current指针指向新任务,然后长跳转到新任务状态段TSS。
3、跳转造成任务切换,CPU会进行保存旧的TSS,载入新TSS的动作。

进程终止步骤如下
1、中止进程调用exit()系统调用。进入内核函数do_exit()。
2、释放进程代码段和数据段所占用内存页面,关闭打开的文件,对当前工作目录,根目录和程序的i节点进行同步操作。
3、如果有子进程则让init进程接管,如果是会话首领并有控制终端,则释放控制终端并向所有会话进程发送SIGHUP信号。
4、把进程设置为僵死状态,并向父进程发送SIGCHLD信号提醒过来收尸。
5、do_exit()调用调度函数。

分享到:
评论

相关推荐

    嵌入式Linux C编程入门(第2版) PPT

    第5章 嵌入式linux c语言基础——控制语句及函数 138 5.1 嵌入式linux c语言程序结构概述 138 5.1.1 嵌入式linux c语言3种程序结构 138 5.1.2 嵌入式linux c语言基本语句 139 5.2 选择语句 142 5.2.1...

    Android底层开发技术实战详解--内核、移植和驱动.(电子工业.王振丽).part3

    第5章 goldfish下的驱动解析 125 5.1 staging驱动 125 5.1.1 staging驱动概述 125 5.1.2 binder驱动程序 126 5.1.3 logger驱动程序 135 5.1.4 lowmemorykiller组件 136 5.1.5 ...

    嵌入式Linux程序设计案例与实验教程(配套光盘)第三部分

    第5章 嵌入式Linux开源软件移植与应用101 5.1 嵌入式WebServer GoAhead的移植与应用101 5.1.1 嵌入式Web服务器101 5.1.2 GoAhead介绍101 5.1.3 GoAhead在ARM平台上的移植102 5.1.4 页面操作102 实验5.1 嵌入式...

    嵌入式Linux程序设计案例与实验教程(配套光盘)第一部分

    第5章 嵌入式Linux开源软件移植与应用101 5.1 嵌入式WebServer GoAhead的移植与应用101 5.1.1 嵌入式Web服务器101 5.1.2 GoAhead介绍101 5.1.3 GoAhead在ARM平台上的移植102 5.1.4 页面操作102 实验5.1 嵌入式...

    嵌入式Linux程序设计案例与实验教程(配套光盘)第二部分

    第5章 嵌入式Linux开源软件移植与应用101 5.1 嵌入式WebServer GoAhead的移植与应用101 5.1.1 嵌入式Web服务器101 5.1.2 GoAhead介绍101 5.1.3 GoAhead在ARM平台上的移植102 5.1.4 页面操作102 实验5.1 嵌入式...

    嵌入式Linux程序设计案例与实验教程-实例代码

    第5章 嵌入式Linux开源软件移植与应用101 5.1 嵌入式WebServer GoAhead的移植与应用101 5.1.1 嵌入式Web服务器101 5.1.2 GoAhead介绍101 5.1.3 GoAhead在ARM平台上的移植102 5.1.4 页面操作102 实验5.1 ...

    寒江独钓-Windows内核安全编程(高清完整版).part4

    有助于读者熟悉Windows内核驱动的体系结构,并精通信息安全类的内核编程技术。本书的大部分代码具有广泛的兼容性,适合从Windows 2000 一直到目前最新的Windows 7 Beta 版。  本书适合大专院校计算机系的学生、...

    精通LINUX设备驱动程序开发

    79 4.6 查看源代码 79 第5章 字符设备驱动程序 81 5.1 字符设备驱动程序基础 81 5.2 设备实例:系统cmos 82 5.2.1 驱动程序初始化 83 5.2.2 打开与释放 86 5.2.3 数据交换 88 5.2.4 查找 92 5.2.5 控制 ...

    linux编程.pdf

    - **概述**:深入分析了UNIX/Linux系统中的进程概念及其管理。 - **学习要点**: - 进程的生命周期。 - 进程创建的方法。 - 进程调度的基本原理。 #### 三、进程控制 **3.1 进程的建立与运行** - **概述**:...

    Android底层开发技术实战详解--内核、移植和驱动.(电子工业.王振丽).part1

    第5章 goldfish下的驱动解析 125 5.1 staging驱动 125 5.1.1 staging驱动概述 125 5.1.2 binder驱动程序 126 5.1.3 logger驱动程序 135 5.1.4 lowmemorykiller组件 136 5.1.5 ...

    Android底层开发技术实战详解--内核、移植和驱动.(电子工业.王振丽).part2

    第5章 goldfish下的驱动解析 125 5.1 staging驱动 125 5.1.1 staging驱动概述 125 5.1.2 binder驱动程序 126 5.1.3 logger驱动程序 135 5.1.4 lowmemorykiller组件 136 5.1.5 ...

    Linux高性能服务器编程

    4.6 HTTP通信 4.6.1 HTTP请求 4.6.2 HTTP应答 4.7 实例总结 第二篇 深入解析高性能服务器编程第5章 Linux网络编程基础API 5.1 socket地址API 5.1.1 主机字节序和网络字节序 5.1.2 通用socket地址 5.1.3 ...

    集群好书《高性能Linux服务器构建实战》 试读章节下载

    13.2 Oracle ClusterWare体系结构与进程介绍 13.2.1 Oracle ClusterWare 简介 13.2.2 Oracle ClusterWare 进程介绍 13.3 RAC数据库体系结构与进程 13.3.1 RAC 简介 13.3.2 Oracle RAC的特点 13.3.3 RAC...

    Unix操作系统设计

    第5章 文件系统的系统调用 5.1 系统调用Open 5.2 系统调用read 5.3 系统调用write 5.4 文件和记录的上锁 5.5 文件的输入/输出位置的调整lseek 5.6 系统调用close 5.7 文件的建立 5.8 特殊文件的建立 5.9 改变...

    寒江独钓-Windows内核安全编程(高清完整版).part1

    有助于读者熟悉Windows内核驱动的体系结构,并精通信息安全类的内核编程技术。本书的大部分代码具有广泛的兼容性,适合从Windows 2000 一直到目前最新的Windows 7 Beta 版。  本书适合大专院校计算机系的学生、...

    Linux网络编程-宋敬彬+孙海滨等编著

    - **概述:** 描述了互联网体系结构模型的特点,与OSI模型相比,它更加简化和实用。 - **知识点:** - 应用层、传输层、网络层、网络接入层的基本功能。 - 各层之间的工作原理及相互关系。 **1.4 客户/服务器模型...

    寒江独钓-Windows内核安全编程(高清完整版).part3

    有助于读者熟悉Windows内核驱动的体系结构,并精通信息安全类的内核编程技术。本书的大部分代码具有广泛的兼容性,适合从Windows 2000 一直到目前最新的Windows 7 Beta 版。  本书适合大专院校计算机系的学生、...

Global site tag (gtag.js) - Google Analytics