编程语言发展
为了提升编程效率,最早创造了汇编语⾔的概念。其实汇编语⾔和机器语⾔(也就是指令)直接是完 全⼀⼀对应的,只是相对于0、1这些数字,发明了⼀些帮助⼈类记忆和理解的符号将其对应起来,也就是我们上⾯看到的类似LOAD_A、LOAD_B等。程序员完成编程之后,需要使⽤汇编器 (assembler)将汇编语⾔翻译成机器语⾔。虽然汇编降低了程序员的记忆成本,但要求程序还是必须掌握计算机硬件的所有知识,⽽且随着计算 机⼚商越来越多,⼀次编写的程序往往只适⽤于⼀类计算机。这个是远远不够的,所以更为⾼级的语 ⾔诞⽣了,⾼级语⾔屏蔽了硬件细节,让程序员可以站在更⾼的层⾯上思考自己的业务。这⾥以C语 ⾔为例,程序员完成程序的编写之后,需要使⽤编译器(compiler)和连接器(linker)将程序翻译成 汇编语⾔,再借助汇编器变成最终的机器语⾔。 借助封装的思想,我们学习编程变得越来越容易。不过有利则有弊,⾼度的抽象,导致很多的程序员 把计算机视为⼀个⿊箱,完全⽆法理解⾃⼰的程序是如何⼯作起来的,希望我们⼤家不要做这种程序 员。 我们使⽤的Java语⾔相对于C语⾔更⾼级⼀点,但基本抽象原理上没有太⼤的差异,我们暂时就不展 开说明了。
注意:⾼级语⾔的⼀条语句(Statement)往往对应很多条指令(Instruction)才能完成。
操作系统(Operating System)
操作系统是⼀组做计算机资源管理的软件的统称。⽬前常⻅的操作系统有:Windows系列、Unix系 列、Linux系列、OSX系列、Android系列、iOS系列、鸿蒙等。
操作系统的定位
操作系统由两个基本功能:
1)防⽌硬件被时空的应⽤程序滥⽤;
2)向应⽤程序提供简单⼀致的机制来控制复杂⽽⼜通常⼤相径庭的低级硬件设备。
什么是进程/任务(Process/Task)
每个应⽤程序运⾏于现代操作系统之上时,操作系统会提供⼀种抽象,好像系统上只有这个程序在运 ⾏,所有的硬件资源都被这个程序在使⽤。这种假象是通过抽象了⼀个进程的概念来完成的,进程可 以说是计算机科学中最重要和最成功的概念之⼀。
进程是操作系统对⼀个正在运⾏的程序的⼀种抽象,换⾔之,可以把进程看做程序的⼀次运⾏过程; 同时,在操作系统内部,进程⼜是操作系统进⾏资源分配的基本单位。
进程控制块抽象(PCB Process Control Block)
计算机内部要管理任何现实事物,都需要将其抽象成⼀组有关联的、互为⼀体的数据。在Java语⾔中,我们可以通过类/对象来描述这⼀特征。
// 以下代码是 Java 代码的伪码形式,重在说明,⽆法直接运⾏
class PCB {
// 进程的唯⼀标识 —— pid;
// 进程关联的程序信息,例如哪个程序,加载到内存中的区域等
// 分配给该资源使⽤的各个资源
// 进度调度信息(留待下⾯讲解)
}
这样,每⼀个PCB对象,就代表着⼀个实实在在运⾏着的程序,也就是进程。 操作系统再通过这种数据结构,例如线性表、搜索树等将PCB对象组织起来,⽅便管理时进⾏增删查 改的操作。
CPU分配——进程调度(Process Scheduling)
为了便于讨论和理解,我们⼤部分的场景下假设是单CPU单核的计算机。 操作系统对CPU资源的分配,采⽤的是时间模式——不同的进程在不同的时间段去使⽤CPU资源。
内存分配——内存管理(Memory Manage)
操作系统对内存资源的分配,采⽤的是空间模式——不同进程使⽤内存中的不同区域,互相之间不会⼲扰。
进程间通信(Inter Process Communication)
如上所述,进程是操作系统进⾏资源分配的最⼩单位,这意味着各个进程互相之间是⽆法感受到对⽅ 存在的,这就是操作系统抽象出进程这⼀概念的初衷,这样便带来了进程之间互相具备”隔离性 (Isolation)“。
但现代的应⽤,要完成⼀个复杂的业务需求,往往⽆法通过⼀个进程独⽴完成,总是需要进程和进程 进⾏配合地达到应⽤的⽬的,如此,进程之间就需要有进⾏“信息交换“的需求。进程间通信的需求 就应运⽽⽣。 ⽬前,主流操作系统提供的进程通信机制有如下:
1. 管道
2. 共享内存
3. ⽂件
4. ⽹络
5. 信号量
6. 信号
其中,⽹络是⼀种相对特殊的IPC机制,它除了⽀持同主机两个进程间通信,还⽀持同⼀⽹络内部⾮ 同⼀主机上的进程间进⾏通信。