同步与互斥的基本原理

在本科学习过《操作系统》的同志们都知道,现代操作系统提供了一个并发控制环境,即系统中同时活动着的多个不同的进程,这些进程共享同一个CPU、内存或 I/O设备。特别是对于Linux这种世界上最先进的操作系统来说,其多任务、多用户、分时实时混合的性质决定了多个进程在某种程度上彼此依赖或相互制约的关系,这些关系我们叫“并发关系”,按其性质可以分为同步(synchronization)和互斥(mutual exclusion)两类。

本篇博文,我们就对同步和互斥的一些基本概念进行一下梳理,以便在以后的工作中能由一个明确的概念。

临界资源:系统中同时存在有许多进程,它们共享各种资源,然而有许多资源在某一时刻只能允许一个进程使用。例如打印机、磁带机等硬件设备和变量、队列等数据结构,如果有多个进程同时去使用这类资源就会造成混乱。因此必须保护这些资源,避免两个或多个进程同时访问这类资源。我们把某段时间内只能允许一个进程使用的资源称为临界资源。

互斥:进程间相互排斥的使用临界资源的现象,就叫互斥,很简单。

同步:对比前面的互斥概念,还有一种并发关系叫做同步,即进程之间的关系不是相互排斥临界资源的关系,而是相互依赖的关系。进一步的说明:就是前一个进程的输出作为后一个进程的输入,当第一个进程没有输出时第二个进程必须等待。

临界区:几个进程若共享同一临界资源,它们必须以互相排斥的方式使用这个临界资源,即当一个进程正在使用某个临界资源且尚未使用完毕时,其它进程必须延迟对该资源的操作,当使用该资源的进程释放该资源时,其它进程才可使用该资源,任何进程不能从中插进去使用这个临界资源,否则将会造成信息混乱和操作出错。我们把访问临界资源的代码段称为临界区。

并发环境有伪并发(单处理器)和真并发(多处理器)之分,但是都会造成竞争条件。用户空间之所以需要同步,是因为用户程序会被调度程序抢占和重新调度。在Linux中,造成并发执行的原因大致有如下几条:

   1. 中断
   2. 软中断和tasklet
   3. 内核抢占——任务的优先级
   4. 睡眠及用户空间的同步
   5. SMP —— 多处理器

其中,1、2、3、4条属于伪并发,第5条属于真并发。

不管是真并发,还是伪并发,其本质都是系统中存在了独占资源,处理而并发进程控制其实是很困难的,有以下三座大山需要解决:

1、并发进程在争用有限的全局共享资源时容易引起冲突。
2、由于进程被调度执行的顺序是动态的和随机的,所以操作系统很难最佳的管理资源分配。
3、程序的执行结果和系统执行速度有关。

下面,我们就来看看Linux是怎么解决上述三大问题的。

首先,第一个问题,Linux是通过进程控制块解决的,整个解决方法是围绕一个核心数据结构—— task_struct,给所有进程规定一些状态,并建立一系列的算法。我们会在进程控制专题中详细讨论。

第二个问题,关于资源的分配管理,主要有处理器分配、内存分配、文件系统访问和I/O设备的使用。对于Linux来说,是通过进程调度、虚拟内存管理、文件管理和I/O设备管理模块来解决的。我们也会在相应的专题来重点讨论。

最后一个问题,其实你好好的分析一下,可以看出,这个问题其实是解决前两个问题后所带来的一个新问题,即Linux必须解决程序的结果与进程的执行速度及先后次序无关的问题。这,也是我们本专题重点讨论的问题。

最后一个问题我们再进一步分析一下,我们要解决同步与互斥,其实本质上是要解决两个问题:死锁和饥饿。

死锁的问题大家很熟悉了,这里不再赘述,我重点谈谈饥饿。饥饿是多进程对临界资源互斥访问的另一种问题,如果某种资源分配算法表面上看似很合理,但可能在一段时间内或无限期地使系统中的某些进程得不到服务,或者说这些进程访问资源时被无限期地拒绝,我们就称这种现象叫做“饥饿”

综上所述,在并发程序中为了防止竞争条件,除了要做到互斥和同步外,还得保证并发进程不会出现“死锁”、“饥饿”现象。所以,Linux提出了一下四种原则来保障并发程序的可执行性:

1、每次只允许一个进程进入临界区
2、如果某个进程进入临界区,其他试图进入该临界区的进程必须等待
3、当多个进程申请进入同一临界区时,在有限时间内让其中之一进入临界区
4、位于临界区的进程只能逗留有限时间,时间一到立即让出

好了,关于同步与互斥最基本的概念就介绍到这里。虽然文章不长,但内容十分重要,本专题后面将具体讲解Linux内核中使用的同步与互斥机制的各种实现方式,希望大家在分析每种方式的时候,都不要忘了回头来看看这篇文章,做到实际联系理论,感性联系理性。

你可能感兴趣的:(疯狂内核之同步与互斥)