第17章 互斥量的设计与实现

来源:互联网 发布:网络调试助手连不上 编辑:程序博客网 时间:2024/05/16 17:22
当所有的任务在同个单一地址空间下,使用共享资源时,必然涉及到共享资源的竞争。只有多个任务互斥地访问共享资源时才不会发生错误。只有提供互斥或信号量才能保证内核并发机制。

任何互斥尝试必须基于一些基础硬件互斥机制。最常见的这种约束是某一时刻对内存的一次访问。(intel处理器可以查看《IA-32架构软件开发人员指南 卷3 系统编程指南》中7.1节 加锁的原子操作)

x86上实现互斥,需要硬件的支持:
1、中断禁用。代价高,在单CPU上能使用。在多CPU上不能使用(多处理器中,是对等关系,没有支持互斥的中断机制)。
2、专用机器指令:在一个指令的执行周期内对一个存储单元的读和写(xchg) 或 测试和设置(testset)。在该指令的执行过程中,任何其他指令访问内存将被阻止。

IA-32处理器提供了LOCK#信号。这个信号会在某些内存操作过程中被自动发出。当做这个输出信号发出的时候,来自其他处理器或总线代理的总线控制请求将被阻塞。软件能够利用在指令前添加LOCK前缀来指定,在其他情况下也需要LOCK语义(LOCK semantices)。

在Intel 386 ,Intel 486,Pentium处理器中,直接调用加锁的指令会导致LOCK#信号的产生。硬件的设计者需要保证系统硬件中LOCK#信号的有效性,以控制多个处理器对内存的访问。对与Pentium 4,Intel Xeon,以及P6系列处理器,如果被访问的内存区域存在于处理器内部的高速缓存中,那么LOCK#信号通常不被发出;但是处理器的缓存却要被锁定。

xchg指令会自动的带有LOCK 语义。

mutex.h源代码如下所示
#ifndef_MUTEX_H_#define _MUTEX_H_typedef unsigned long mutex_t;static inline unsigned long xchgl(unsigned long x, unsigned long *ptr){    __asm__ __volatile__("xchgl %0,%1\n\t"        :"=r"(x)        :"m"(*ptr),"0"(x)        :"memory"        );    return x;}/*mptr是mutex_t的指针*/#define lock(mptr) ({\    while(xchgl(1,(mptr)));\})/*mptr是mutex_t的指针*/#define unlock(mptr) xchgl(0,(mptr))/*mptr是mutex_t的指针*/#define init_mutex(mptr) ({*mptr = 0;})#endif



原创粉丝点击