读书人

《当代操作系统》读书笔记之进程间

发布时间: 2012-06-30 17:20:12 作者: rapoo

《现代操作系统》读书笔记之——进程间通信3

? ? 12.互斥量(mutex)

? ? 当信号量(Semaphore)的计数功能不再需要,信号量简化之后就成为一种新的变量互斥量(mutex)。互斥量在处理共享资源和代码之间的互斥访问方面非常有用。互斥量实现起来简单高效,这一点对于用户空间的线程库非常有用。

? ? 互斥是那种只有两种状态,但每次只能处在其中一种状态的变量。这两种状态分别是锁定和非锁定状态。因此,只需要一个比特就能表示互斥量的两种状态,例如,0代表非锁定和1表示锁定。互斥量有两个相关的操作:mutex_lock和mutex_unlock。

? ? mutex_lock:当线程需要进入临界区时,它调用mutex_lock操作,若当前mutex未锁定,则mutex_lock调用成功,若mutex已经锁定,则调用线程会阻塞,直到当前获得mutex锁的那个线程离开临界区,使得mutex解锁。

? ? mutex_unlock:当线程离开临界区,需要解除对mutex的锁定,这时候线程调用mutex_unlock。mutex很简单,因此在用户空间可以很简单的通过TSL和XCHG指令实现,其原理的代码如下:

?

mutex_lock:TSL REGISTER,MUTEXCMP REGISTER,#0JZE ok| 如果mutex为0,则证明mutex目前未锁定,于是返回CALL thread_yieldJMP mutex_lock| 再次尝试ok: RETmutex_unlock:MOVE MUTEX,#0| 解锁:将mutex设置为0RET
? ? 这个代码和前面讲到的enter_region的代码非常类似,但是却有一个很关键的区别:在enter_region中,如果进程暂时不能进入临界区,那么他一直测试条件,看能否进入,直到时间片用完为止。

?

? ? 而在用户线程中,根本没有时钟中断来使得运行过长的线程停下来,结果就是一个使用上述的忙等待方式企图获取锁的线程会时钟循环,因为别的获得锁的线程根本没机会运行。

? ? 而在mutex_lock中则不同,如果当前mutex锁定,他就阻塞,让调度机调度其他的线程运行,从而更加充分的利用CPU资源。

? ? 由于thread_yield仅仅是在用户空间对线程调度器的调用,因此,不需要内核支持,这样实现起来是很简单的。

? ? 除了mutex_lock和mutex_unlock之外,可能还需要其他的一些特性,例如mutex_trylock,该调用会尝试获得锁,但是如果不成功就以失败状态返回,然后该干嘛干嘛,至少并不阻塞。

? ? 由于线程之间共享一个内存空间,所以对于多个线程来说,共享mutex不是什么难事。但是之前提到的Peterson方案、信号量方案等主要是对于进程来说的。他们之间并不共享一份内存空间。那怎么保证多个进程之间共享变量,例如之前提到的turn呢?至少有这么几种办法:

?

读书人网 >操作系统

热点推荐