什么是同步互斥问题?
引入了进程和线程的概念以后,多个进程和线程可以并发地在处理器中执行。在实际应用中,它们并不是独立地自己执行自己的,有时候会存在多个进程协作完成一个更大的任务。例如前面在进程管理(1):线程和进程的概念中提到的例子,一个MP3播放器软件,被划分为I/O读取数据,解压数据,和播放解压后的音频文件三个子模块,我们可以使用三个线程来实现这三个子模块,I/O操作总是把数据读到某一个缓冲区,解压操作则到这个缓冲区去读取数据。考虑一种情况,由于线程的调度,解压的线程先于I/O的线程得到执行,此时它去读取缓冲区的数据,就只能得到无意义的数据。
上面这个例子说明了进程之间同步运行的概念,即一些进程的操作一定要先于另一些进程的操作执行,否则就会导致致命性的问题。同步又称为进程之间的直接制约关系,它本质上是源于进程之间的相互合作。
互斥问题则更加普遍,在没有协作的进程之间也有可能发生。例如在前面讲过,在进程创建时,需要为它分配唯一的标志符pid
,具体的操作通过内核函数get_pid
来实现。其中的主要操作是:
new_pid = next_pid++;
return new_pid;
这里的next_pid
存储了下一个可用的pid
,进程申请pid
时,直接将这个next_pid
分配给该进程即可,然后next_pid++
存储下一个可用的pid
。上面代码的汇编指令是:
LOAD next_pid REG1
STORE REG1 new_pid
INC REG1
STORE REG1 next_pid
考虑有两个新创建的进程都请求操作系统分配一个新的pid
,假定当前next_pid = 100
,则预期两个进程被分配到pid = 100
和pid = 101
,并且next_pid
增加到102
。但是如果在为一个进程分配pid
时发生了调度,例如在第二行调度到了另一个进程,如下图所示:
程序执行完毕后,两个进程都将分配到pid = 100
,并且next_pid = 101
,这对于操作系统显然是一个致命性的错误。
这个例子说明,对于操作系统中某些共享资源,例如外部设备,全局变量,一次是只允许一个进程访问的,否则就会出现难以预料的错误。互斥就是指进程之间这种访问的制约关系,又称为间接制约关系,这里要互斥访问的资源,被称为临界资源。以下首先探讨如何解决互斥问题。
临界区的概念
临界区(critical section
)是指进程中访问临界资源的一段需要互斥执行的代码。在进入临界区之前的区域被称为进入区(entry section
),通常需要在该段区域获得对资源的互斥访问权限。临界区之后的部分被称为退出区exit section
,在这里释放资源的互斥访问权限。剩下的区域成为剩余区。这样,进程的代码就组织成了下面的形式:
entry_section
{
critical_section
}
exit_section
remainder_section
对临界区的访问原则,可以抽象为下面的四条规则,即
忙则等待
;指有进程在临界区时,其他想要进入临界区的进程必须等待。空闲则入
;指没有其他进程访问临界区时,可以对临界区进行访问。有限等待
;等待临界区资源的进程不能无限地等待下去。让权等待
;指进程在等待进入临界区时,应该放弃CPU的使用权,进入阻塞状态。这一条是可选的。
为了实现上面四条对临界区的访问规则,有三种具体的方式,即禁用中断、软件方法和高级抽象方法,将在下面一一进行叙述。
禁用中断
对上面的互斥问题进行分析,可以发现,之所以会引发临界区的冲突访问,其根源在于一个进程在访问临界区时发生了进程的调度,使得另一个进程也进入了临界区进行访问。因此,我们可以从根源上来解决这个问题,即在进程访问临界区时禁止调度,禁用中断就是这样一种方法。
这样,访问临界区的代码,就可以组织成下面的形式:
local_irq_save(unsigned long flags);
critical_section
local_irq_restore(unsigned long flags);
即在进入临界区之前禁用中断,执行完临界区代码后再使能中断。为了禁用中断,需要将cr0
寄存器中的中断标志位FL_IF
清零,在使能中断时再将该位置一。所以看到在禁用中断时需要保存当前的状态标志,在使能中断时恢复这些状态标志。
这种方法是切实有效的,只是容易看出,稍微有点简单粗暴。在禁用中断后,当前进程就不能被停止,如果此时进程出现了错误,就会导致整个系统都停止运行;又或者临界区可能很长,此时将不能响应硬件中断了。因此,这种方法需要小心使用,一般只有在迫不得已的时候才使用。
软件方法
为了实现临界区的互斥访问,另一种想法是所有要进入临界区的进程共享一些访问标志位,首个进入临界区的进程通过设置这些标志位“通知”其他进程【我已经在临界区了嘻嘻嘻,你们现在不能进来】,这就好比在农村上厕所,又没有锁,只能在厕所外放置一条红丝带之类的东西来告知【已经有人了】。这种方法就是软件方法,它的本质其实