讲起操作系统,想必现代人都不陌生,特别是移动通信这么发达的今天,每个人每天都要刷几个小时的手机,与其说使用手机,不如说手机陪伴你,这些手机使用这么流畅,应用这么丰富,这背后的功劳离不开一个底层基础软件的功劳,那就是手机的操作系统。
手机可以简单拆分为两个部分:硬件+软件。硬件是软件的基石,所有的软件功能最终都是由硬件来实现,这是因为软件是架构在硬件之上,然后逐层不断抽象堆叠起来的。如果剥离软件,让一个使用者使用硬件,你会发现相当的痛苦,需要了解不同硬件的使用方式,并且了解每个硬件的特点,简单来说,没有了软件,硬件就是一堆破铜烂铁。从中,我们也可以看到操作系统的重要性。
冯.诺依曼结构
无论是我们所熟知的PC机,还是手机,还是其他能成为计算机的设备,无不遵循着冯.诺依曼计算机体系,可见冯.诺依曼是多么伟大的计算机科学家,它在1945年发表了一篇关于EDVAC(Electronic Discrete variable Automatic Computer,电子离散变量自动计算机)的论文。
就在这篇文章中提出了对于计算机领域产生深远影响的两个观点:
1,采用二进制,抛弃十进制
2,程序存储
二进制极大简化了计算机设备的逻辑线路,程序能存储,程序指令和数据都存储在同一个内存储器中,除了存储器,还有运算器、控制器、输入输出设备的,我画了简单的示意图,如下:
从中可以看到,一个计算机基本包含这几个部分:CPU(中央处理器)、内存储器、输入输出设备(I/O设备)。
什么是操作系统
计算机发展到今天,市面上可选择的操作系统已经很多了,如果分类的话有:桌面型操作系统、服务器操作系统、嵌入式操作系统。我们使用的手机可以理解为嵌入式操作系统,常见的有Android系统和IOS系统,我们日常办公用的电脑可以理解为桌面型操作系统,比如常见的Windows系统、Mac系统,而服务器操作系统更多选择Linux系列。
操作系统提供了可用的人机交互界面,比如打开手机,就能四处点点,这里滑一滑,没有用户使用学习成本,上手就可操作,这些都得益于操作系统预装的各种人机交互程序。出了有整体封装的人机交互界面接口之外,还有OS生态圈这个关键点,比如整体第三方应用程序丰富多彩,这也是一个成功的操作系统能够流行普及的主要原因。
因此,操作系统肩负两个重大责任:面向下层-管理硬件,各种硬件设备集中调度,面向上层-提供各种友好的人机交互界面,为第三方程序研发提供便捷、可靠、高效的API接口功能。
所以简单来说,计算机操作系统是负责管理系统硬件,并为上层应用提供稳定编程接口和人机交互界面的软件集合。
进程间通信
我们知道操作系统中的各个进程通常运行与独立的内存空间,并且有严格的机制来防止进程间的非法访问。比如我们熟知的Android系统,每个应用如果需要使用系统的私有数据,就需要向操作系统申请,也就是说要声明使用哪些权限,操作系统才允许应用具体使用,这也是每个Android应用在进程沙盒运行,也是Android系统安全架构的出发点。
虽说每个进程是独立运行,但不代表进程与进程之间不允许互相通信,反而恰恰相反,现实很多软件产品需要多进程协作才能使用流畅,进程间通信(Inter-process communication,IPC)是操作系统中一个重要的概念,应用非常广泛。
那么常见的IPC机制有哪些呢。如下:
- 共享内存。由于两个进程可以直接共享访问同一内存区域,减少了数据的复制操作,因而速度上的优势比较明显。比如在Linux中可以通过shmget函数来实现创建内存共享区,这里会生成共享内存块与某个特定的key进行绑定,用shmat函数来实现进程映射,其他进程然后利用key值来映射自己的内存空间。
- 管道。管道很形象的描述了通信双方的行为,即进程A与进程B,管道一般是单双工通信,如果需要既要“读”和“写”的话,需要建立两个管道。同时管道有容量限制,读为空的时候,需要阻塞,等待有可读内容过来,写满的时候,需要阻塞,等到继续可写入的时候,再写。
- Socket。这个更多应用于网络通信,基于TCP/IP协议,有客户端和服务端两种角色,服务端负责监听IPC请求,客户端发起IPC请求,双方建立起IPC连接。
- RPC。这个一般应用于通信双方运行在不同的机器上,对于上层调用人员来说不需要特别关心具体的中间传输过程是如何实现的,这种“透明性”可以较大程度地降低研发难度。
同步机制
我们经常会听到资源锁同步,因为在现代操作系统中一个任务完成不仅仅是单线程执行到底的,而往往是需要多线程协同执行,这里面如何保证系统资源同步就显得至关重要了。
从严格意义来说,如果多个进程间存在时序关系,需要协同工作完成一个任务,则称为同步。如果资源具有排他性,那么此时的关系可以称为互斥。那么常见的同步机制有哪些呢?如下:
- 信号量(Semaphore)。Semaphore S,Operation P也叫wait(),Operation V也叫signal()。其中S表示共享资源的可用数量,P可以减小S计数,V则增加它的计数。比如进去共享区时,首先执行P操作,同理,要退出共享区时,执行V操作。其中PV操作是具有原子性,意味着它们在执行过程中是不允许被中断的。
- Mutex,又称为互斥体。Mutex通常是对某一排他性资源共享控制,要么资源被占用,要么就是可以访问。
- 管程。是可以被多个进程安全访问的对象,也就是在同一时刻只允许有一个访问者使用它们,还具有安全性、互斥性、共享性。
内存管理
不管是什么操作系统,内存管理都是绝对的重点。可以说操作系统运行基本都是玩内存的游戏,比如虚拟内存、内存分配与回收、内存保护等。
1,虚拟内存。
虚拟内存的出现主要为了解决大体积程序的问题。它将外部存储器部分空间作为内存的扩展,比如从硬盘划分出4G大小,当内存资源不足时,系统将按照一定算法自动挑选优先级低的数据块,并且将它们存储在硬盘中,后续如果用到这些数据库,系统将产生“缺页”指令,然后把它们交换到内存中,这些操作都是系统内核自动完成的,对于上层来说是完全透明的。
2,内存分配与回收。对于应用程序来说,内存的分配和回收是它们最关心的,一般核心问题是要保证硬件无关性、动态分配内存和回收、内存碎片。比如在Linux系统中常见的mmap()函数,可以将某个设备或文件映射到英语进程的内存空间中,这样访问内存就相当于对设备或文件进行读写,而不需要通过read()、write(),同时通过mmap函数,因为映射同一块物理内存来共享内存,也减少了数据复制的次数,在一定程度上提高进程间通信的效率。
小结
我们从冯.诺依曼计算机体系开始,强调了操作系统的重要的几个特性,进程间通信机制、同步机制、内存管理机制,从这几个点切入,才能逐步去了解操作系统的面纱。同样,对于所处的上层开发来说,在日常工作中经常会碰到相关应用程序的性能问题,其实很多性能问题基本都涉及进程和同步概念,内存管理问题,如果进一步了解操作系统的特性,那么对于解决性能类问题其实是如虎添翼。