Chapter 3 进程管理

3.1 进程

  1. 进程就是处于执行期的程序(目标码存放在某种存储介质上),但进程并不仅仅局限于一段可执行程序代码。通常进程还要包含其他资源,像打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程。当然还包括用来存放全局变量的数据段等,实际上,进程就是正在执行的程序代码的实时结果,内核需要有效而又透明地管理所有细节。

  2. 执行线程,简称线程,是在进程中活动的对象,每个线程都拥有一个独立的程序计数器、进程栈和一组进程寄存器,内核调度的对象是线程,而不是进程,在传统的Linux系统中,一个进程只包含一个线程,但现在的系统中,包含多个线程的多线程程序司空见惯。Linux系统的线程实现非常特别:它对线程和进程并不特别区分,

  3. 对Linux而言,线程只不过是一种特殊的进程罢了。

  4. 在现代操作系统中,进程提供两种虚拟机制:虚拟处理器和虚拟内存。

  5. 在现代Linux内核中,fork()实际上是由clone()系统调用实现的。

3.2 进程描述符及任务结构

内核把进程的列表存放在叫做任务队列的双向循环链表中。

链表中的每项都是类型为task_struct、称为进程描述符的结构,该结构定义在<linux/sched.h>文件中。

3.2.1 分配进程描述符

3.2.2 进程描述符的存放

3.2.3 进程状态

五种进程状态:运行、可中断、不可中断、被其他进程跟踪的进程、停止

3.2.4 设置当前进程状态

内核需要经常调整某个进程的状态:settaskstate(task,state)函数

3.2.5 进程上下文

可执行程序代码是进程的重要组成部分。这些代码从一个可执行文件载入到进程的地址空间执行。一般程序在用户空间执行。当一个程序调执行了系统调用(参见第5章)或者触发了某个异常,它就陷入了内核空间。此时,我们称内核“代表进程执行”并处于进程上下文中。在此上下文中current宏是有效的。除非在此间隙有更高优先级的进程需要执行并由调度器做出了相应调整,否则在内核退出的时候,程序恢复在用户空间会继续执行。 系统调用和异常处理程序是对内核明确定义的接口。进程只有通过这些接口才能陷入内核执行——对内核的所有访问都必须通过这些接口。

3.3 进程创建

3.3.1 写时拷贝

  1. 传统的fork()系统调用直接把所有的资源复制给新创建的进程,这种实现过于简单并且效率低下,因为它拷贝的数据也许并不共享,更糟的情况是,如果新进程打算立即执行一个新的映像,那么所有的拷贝都将前功尽弃。Linux的fork()使用写时拷贝页实现,写时拷贝是一种可以推迟甚至免除拷贝数据的技术。内核此时并不复制整个进程地址空间,而是让父进程和子进程共享同一个拷贝。

  2. 只有在需要写入的时候,数据才会被复制,从而使各个进程拥有各自的拷贝,也就是说资源的复制只有在需要写入的时候才进行,在此之前,只是以只读方式共享,这种技术使地址空间上的页的拷贝被推迟到实际发生写入的时候才进行在页根本不会被写入的情况下它们就无须复制了。

  3. fork()的实际开销就是复制父进程的页表以及给子进程创建唯一的进程描述符。在一般情况下,进程创建后都会马上运行一个可执行的文件,这种优化可以避免拷贝大量根本就不会被使用的数据(地址空间里常常包含数十兆的数据)由于Unix强调进程快速执行的能力,所以这个优化是很重要的。

3.4 线程在Linux中的实现

线程机制是现代编程技术中常用的一种抽象概念,该机制提供了在同―程序内共享内存地址空间运行的―组线程,这些线程还可以共享打开的文件和其他资源,线程机制支持并发程序设计技术,在多处理器系统上,它也能保证真正的并行处理。 Linux实现线程的机制非常独特,从内核的角度来说,它并没有线程这个概念,Linux把所有的线程都当做进程来实现,内核并没有准备特别的调度算法或是定义特别的数据结构来表征线程,相反,线程仅仅被视为―个与其他进程共享某些资源的进程,每个线程都拥有唯一隶属于自己task_struct,所以在内核中,它看起来就像是一个普通的进程(只是线程和其他一些进程共享某些资源,如地址空间)。

3.4.1创建进程

3.4.2内核线程

内核经常需要在后台执行一些操作,这种任务可以通过内核线程完成——独立运行在内核空间的标准进程。内核线程和普通的进程间的区别在于内核线程没有独立的地址空间。它们只在内核空间运行,从来不切换用户空间去,内核进程和普通进程一样,可以被调度,也可以被抢占。 Linux确实会把一些任务交给内核线程去做,像flush和ksofirqd这些任务就是明显的例子,在装有Linux系统的机子上运行ps -ef命令,你可以看到内核线程,有很多!这些线程在系统启动时由另外一些内核线程创建,实际上,内核线程也只能由其他内核线程创建,内核是通过从kthreadd内核进程中衍生出所有新的内核线程来自动处理这一点的,在<linux/kthreadd>中申明有接口。

3.5 进程终结

当一个进程终结时,内核必须释放它所占有的资源并把这一不幸告知其父进程。

3.5.1 删除进程描述符

3.5.2 孤儿进程造成的进退维谷

    如果父进程在子进程之前退出,必须有机制来保证子进程能找到一个新的父亲否则这些成为孤儿的进程就会在退出时永远处于僵死状态,白白地耗费内存。前面的部分已经有所                暗示于这个问题,解决方法是给子进程在当前线程组内找—个线程作为父亲,如果不行就让init做它们的父进程。

《Linux内核设计与实现》读书笔记四的更多相关文章

  1. 【鸟哥的Linux私房菜】笔记1

    Linux是什么 从操作系统与cpu架构关系到linux  Richard Mathew Stallman GPL 关于GNU计划 Linux的发展 Linux的核心版本 Linux的特色 Linux ...

  2. 【鸟哥的Linux私房菜】笔记3

    正确地开机 最好不要使用root账号登陆!GNOME图形界面 View items as a list X WindowShell 文本交互界面bash是Shell的名称,Linux的默认壳程序就是b ...

  3. 【鸟哥的Linux私房菜】笔记2

    Linux的应用 学习资源整理 安装记录 >< 1.Linux的应用: 网络服务器 数据库 学术机构的高效运算任务 嵌入式系统 ... 2.挂载与磁盘分区 学习资源整理 学习 1.书上的网 ...

  4. 《鸟哥的Linux私房菜》笔记——02. 关于Linux

    Unix 历史 1969年以前:伟大的梦想--Bell, MIT 与 GE 的「Multics」系统 1969年:Ken Thompson 的小型 file server system 1973年:U ...

  5. 《鸟哥的Linux私房菜》笔记——03. 磁盘分区

    Everything is a file. 常见硬件对应于 Linux 下的文件(/dev目录下) 装置 装置在Linux内的档名 SCSI/SATA/U盘硬盘机 /dev/sd[a-p] U盘 /d ...

  6. 鸟哥的linux私房菜学习笔记 __ 命令与文件的搜寻

    连续输入两次[tab]按键就能够知道使用者有多少命令可以下达.那你知不知道这些命令的完整档名放在哪里?举例来说,ls 这个常用的命令放在哪里呢? 就透过 which 或 type 来找寻吧! 范例一: ...

  7. 【鸟哥的Linux私房菜】笔记

    操作系统核心的功能! 驱动程序与操作系统的关系 2. [计算机组成之组件] 3.CPU实际要处理的数据完全来自于主存储器,这是一个很重要的概念! 4.CPU是整个计算机系统最重要的部分,那么目前世界上 ...

  8. 《鸟哥的Linux私房菜》笔记——04. 简单命令行

    键入命令 [dmtsai@study ~]$ command [-options] parameter1 parameter2 ... 指令 選項 參數(1) 參數(2) 注意:有时也可以使用 + 放 ...

  9. 鸟哥的Linux私房菜学习笔记——文件权限与目录配置

    Linux的文件权限和目录配置 在linux中的每个用户必需属于一个组,不能独立于组外.在linux中每个文件有所有者.所在组.其它组的概念. (1)所有者 一般为文件的创建者,谁创建了该文件,就是天 ...

  10. 鸟哥的Linux私房菜学习笔记(1)

    2014/10/29 1.档案的权限管理分为三个部分: 拥有者.群组.其他 2.ls -al 命令可以看到档案的详细信息 3.档案的属性中由十个部分构成 第一个部分是档案类型 -代表档案.d代表文件夹 ...

随机推荐

  1. asp.net core 如何集成kindeditor并实现图片上传功能

     准备工作 1.visual studio 2015 update3开发环境 2.net core 1.0.1 及以上版本  目录 新建asp.net core web项目 下载kindeditor ...

  2. hadoop系列 第二坑: hive hbase关联表问题

    关键词: hive创建表卡住了 创建hive和hbase关联表卡住了 其实针对这一问题在info级别的日志下是看出哪里有问题的(为什么只能在debug下才能看见呢,不太理解开发者的想法). 以调试模式 ...

  3. 使用idea搭建SSM框架

    搭建个SSM框架居然花费了我好长时间!特此记录! 需要准备的环境: idea 2017.1 jdk1.8 Maven 3.3.9  请提前将idea与Maven.jdk配置好,本次项目用的都是比较新的 ...

  4. 代码编辑器monaco-editor之基础使用

    1.下载安装monaco-editor npm install monaco-editor 我的安装目录在 C://Windows//SystemApps//Microsoft.MicrosoftEd ...

  5. QT中子目录调用另一个子目录

    解决办法: 第一:建立一个subdirs项目,子项目管理 第二:添加二个子项目例如:A子项目   B子项目 第三:现在A子项目调用 B子项目 在A子项目中:右键>添加库>内部库(把A添加进 ...

  6. 乱入Linux界的我是如何学习的

    欢迎来到建哥学Linux,咳!咳!咳!开个玩笑哈,我是一个IT男,IT界的入门选手,正在学习Linux. 在之前,一直想进军IT界,学习IT技术,但是苦于没有人指导,也不知道学什么,最开始我自己在网上 ...

  7. 关于java中BufferedReader的read()及readLine()方法的使用心得

    BufferedReader的readLine()方法是阻塞式的, 如果到达流末尾, 就返回null, 但如果client的socket末经关闭就销毁, 则会产生IO异常. 正常的方法就是使用sock ...

  8. 深入浅出的webpack4构建工具---比mock模拟数据更简单的方式(二十一)

    如果想要了解mock模拟数据的话,请看这篇文章(https://www.cnblogs.com/tugenhua0707/p/9813122.html) 在实际应用场景中,总感觉mock数据比较麻烦, ...

  9. vmware 12中安装苹果系统

    我用的系统是win10... 一.所需软件: 1.下载并安装VMware Workstation Pro 12 密码:7ybc和序列号 密码是:bwm0 2.下载unlocker 203(for OS ...

  10. 2-关于单片机通信数据传输(中断接收,大小端,IEEE754浮点型格式,共用体,空闲中断,环形队列)

    上一篇链接 http://www.cnblogs.com/yangfengwu/p/8628219.html 先说明一点这种方式,不光对于单片机类的,,对于上位机接收数据同样适用----不骗人的,自己 ...