进一步细化程序执行的过程。
在shell加载和执行hello的程序,和hello输出数据,两者都不能够直接操作硬件(主存和I/O设备和处理器),这些操作都是通过操作系统完成的。
操作系统是横亘在应用程序和硬件之间的一个层次。由它来执行对这些硬件的操作。
操作系统的两个主要的任务和功能。
1,保护硬件不被“坏”的程序滥用。2 提供一个简单的机制,来操作底层的,而且分布及其宽泛的硬件。操作系统通过以下的抽象策略来达到其目的。
文件是 I/O设备的抽象,虚拟存储是对存储器和I/O设备的抽象,而进程是对处理器,主存,和I/O设备的抽象。
我们接下来分别来讨论这些抽象的概念。
进程,
拿hello的执行来说,
在我们的例子中,有两个同时的进程,shell 和hello,
开始的时候只有shell被执行,等待命令,当我们要求它执行hello进程的时候,shell将会执行我们的命令,它通过唤醒一个被成为system call的特殊函数,将控制转给操作系统。
操作系统将保存shell的上下文(context),建立新的hello进程和其上下文,然后将控制传给,hello 这个进程。等到hello进程结束的时候,操作系统将恢复shell进程的上下文,并将控制权传给shell,
shell等待下一个命令的传入,
这里运用到的技术叫做,context switch, 进程间如何通信????hello 执行结束后,结果如何在shell中出现???(进程 间的通信问题)
操作 系统就不断的在不同的进程间切换,interleave,这将使程序员很难去得到精确和可以重复的运行时间计算方法。
线程
线程是一个进程下的执行单元,它于很多个兄弟线程在同样的进程上下文环境下工作,并且共享相同的代码和全局变量。
因结构,
为网络服务器对并发的要求,而且不同的线程之间共享数据比不同的进程更方便,所以现在这个编程模型非常重要。
虚拟存储的概念。
虚拟存储是给人一个让人觉得自己在单独使用主存假象的抽象概念。每个进程都有自己对存储的同一视角,叫做,虚拟地址空间,virtual address space,
在linux中,最顶端的四分之一地址空间通常都被用来存储对所有进程都通用的操作系统的代码和数据。剩下的四分之三存储进程自己的数据和代码。地址数字上说是从低往上长。
虚拟地址空间被每个程序看做是几个被很好定义了的区域,每个区域都有自己特别的目 的,我们简要的介绍一下他们,从最低的地址开始,然后往上升。
1,程序代码和数据。
代码从一个固定的地址开始,紧接着跟着数据的位置,这个位置对应的是c语言全局变量。这些代码和数据根据可执行文件的内容直接初始化。 我们的例子中,hello是可执行的。
2,队,
在代码和数据之后紧跟着的马上是运行时的队,不像代码和数据区域,其大小在进程开始的时候是固定的,队在运行时动态的改变它的大小,这是调用c标准类库中如malloc和free的结果。
3,共享的类库,
在地址空间中间部分的区域,这个区域有共享类库的数据和代码,比如说c标准类库,the math类库,
4,堆栈,
在用户的虚拟空间顶端的区域,是用户堆栈,编译器用它来执行函数调用。
就像对一样,用户堆栈根据程序的执行来扩展和收缩。每次我们调用一个函数的时候,堆栈生长,每次我们调用完毕返回的时候,它收缩。堆栈的特点,先进,后出,
5,kernel虚拟存储,
kernel是操作系统的一部分,这部分长时间驻扎在存储中,地址空间的顶端的四分之一是为kernel预留的,应用程序不能够读取和写这部分的内容,或者直接调用由kernel定义的函数。
虚拟内存要工作,需要硬件和操作系统之间进行复杂的交互,其中包括,将处理器产生的每个地址进行硬件翻译
最基本的设想是存储所有处理器虚拟内存的内容在硬盘上,然后用主存作为硬盘的一个高速缓冲存储器。