我就看看操作系统的书,不要求看懂,进程篇
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我就看看操作系统的书,不要求看懂,进程篇相关的知识,希望对你有一定的参考价值。
进程管理和调度
进程类型:二进制代码的应用程序、单线程、分配给应用程序的资源;新进程是fork和exec系统调用产生,还有clone用于实现线程。
命名空间:
概念
C++的命名空间给了用户不同的接口界面。在虚拟化的系统中,一台物理计算机可以运行多个内核。全部资源都通过命名空间抽象起来。本质上,命名空间建立了系统的不同视图。
实现
UTS命名空间,用户命名空间
进程ID号
UNIX进程总是会分配一个号码用于在其命名空间唯一地标识它们,该号码被称作进程ID号,简称PID。
进程ID
除了PID,还有其他的几个ID。
命名空间增加了PID管理的复杂性。
管理PID
内核需要找一个办法来管理所有命名空间内部的局部变量,以及其他ID。
数据结构
函数
生成唯一的PID
为跟踪已经分配和仍然可用的PID内核使用一个大的位图,其中每个PID由一个比特标识。
2.3.4 进程关系
父进程,子进程
2.4 进程管理相关的系统调用
这部分讨论fork和exec系列系统调用的实现。
通常这些调用不是由应用程序直接发出的,而是通过一个中间层调用,即负责与内核通信的C标准库。
从用户态切换到核心态的方法,依不同的体系结构而各有不同。
就目前而言,将内核视为由C标准库使用的“程序库”即可。(虽然内核是个很复杂的东西,但是这里以库调用的视角来看,瞬间就简单了许多,就像java调用包一样简单。)
2.4.1 进程复制
传统的UNIX中用于复制进程的系统调用是fork,但是Linux实现了3个。
(1)fork是重量级调用,创建父进程的一个完整副本
(2)vfork,父子进程间共享数据
(3)clone,产生线程,父子进程之间的共享、复制进行精确控制。
1. 写时复制
复制数据时,进程通常只使用了其内存页的一小部分。(那你怎么知道该复制哪一部分呢?)
2. 执行系统调用
fork、vfork和clone的系统调用的入口点分别是sys_fork、sys_vfork和sys_clone函数。上述函数的任务是从处理器寄存器中提取由用户空间提供的信息,调用体系结构无关的do_fork函数,后者负责进程复制。(这个后者指的是do_fork吧?)
3. do_fork的实现
所有3个fork机制最终都调用了kernel/fork.c中的do_fork(一个体系结构无关的函数)。
4. 复制进程
复制进程的具体工作是在do_fork里面完成。
5. 创建线程时特别问题
用户空间线程库使用clone系统调用来生成新线程。但有一点应该记住,在Linux内核中,线程和一般进程之间的差别不是那么刚性,这两个名词经常用作同义词。
2.4.2 内核线程
内核线程是直接由内核本身启动的进程。
内核线程实际上将内核函数委托给独立的进程,与系统中其他进程“并行”执行。
2.4.3 启动新程序
1. execve实现
该系统调用的入口点是体系结构相关的sys_execve函数,该函数很快将其工作委托给系统无关的进程do_execve例程。
search_binary_handler用于在do_execve结束时查找一种适当的二进制格式,用于所要执行的特定文件。
2. 解释二进制格式
2.4.4 退出进程
进程必须用exit系统调用终止,使得内核有机会将该进程使用的资源释放回系统。
该调用的入口点是sys_exit函数,需要一个错误码作为其参数,以便退出进程。其定义是体系结构无关的,见kernel/exit.c。我们对其实现没什么兴趣,因为它很快将工作委托给do_exit。
简而言之,该函数的实现就是将各个引用计数器减1,如果引用计数器归0而没有进程再使用对应的结构,那么将相应的内存区域返还给内存管理模块。
2.5 调度器的实现
内存中保存了对每个进程唯一描述,并通过若干结构与其他进程连接起来。调度器面对的情形就是这样,其任务是在程序之间共享CPU时间,创造并行执行的错觉。正如以上的讨论,该任务分为两个不同的部分:一个涉及调度策略,另一个设计上下文切换。
以上是关于我就看看操作系统的书,不要求看懂,进程篇的主要内容,如果未能解决你的问题,请参考以下文章